Java 接口集合
我正在编写一个小型 API 来处理具有特定“特征”的对象。在这种情况下,它们都有一个时间间隔和一些其他数据位,因此我编写了一个带有一些 getter 和 setter 的接口 TimeInterval。
现在,大多数 API 方法都处理对象集或对象列表。这些方法在内部使用 Java 集合框架(特别是 HashMap/TreeMap)。因此,这些 API 方法如下所示:
getSomeDataAboutIntervals(List
几个问题:
a) 这应该是 List< 吗?扩展时间间隔>而是用intervalObjects
?
这主要是风格问题吗?我认为严格采用接口的一个缺点是,您需要将列表创建为 List
而不是 List
。 这意味着可能必须将 List
复制到 List
才能将其传递给 API。
还有其他优点吗?这两种方法都有缺点吗?
b) 而且,一个愚蠢的问题:) 集合框架保证我总是得到我放入的相同实例,集合实际上是引用的集合,对吗?
I'm writing a small API to deal with objects that have specific 'traits' In this case, they all have an interval of time and a couple of other bits of data, So I write an interface TimeInterval with some getters and setters.
Now most of these API methods deal with a Set or List of Objects. Internally these methods use the Java Colletions Framework (HashMap/TreeMap in particular). So these API methods are like:
getSomeDataAboutIntervals(List<TimeInterval> intervalObjects);
Couple of Questions:
a) Should this be List<? extends TimeInterval> intervalObjects
instead?
Is it mostly a matter of style? The one disadvantage of taking strictly an interface that I can see is, you need to create your list as a List<TimeInterval>
rather than List<ObjectThatImplementsTimeInterval>
.
This means potentially having to copy a List<Object..>
to List<TimeInterval>
to pass it to the API.
Are there other pros & cons to either approach?
b) And, one dumb question :) The collections framework guarantees I always get out the same instance I put in, the collections are really a collection of references, correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
1)是的。
方法参数应尽可能通用。
列表
比List
更通用,可以在不需要向列表中添加内容时使用。如果您只添加到列表中(而不是从中读取),最通用的签名可能是
List
相反,方法返回类型应该尽可能具体。您很少或永远不想从方法返回通配符泛型。
有时这可能会导致通用签名:
此签名尽可能具体和通用
2) 是的,除了可能在一些罕见的非常具体的情况下(我正在考虑
BitSet
,尽管那不是'从技术上讲,它是一个集合
)。1) Yes.
Method parameters should be as general as possible.
List<? extends A>
is more general thanList<A>
, and can be used when you don't need to add things to the list.If you were only adding to the list (and not reading from it), the most general signature would probably be
List<? super A>
Conversely, method return types should be as specific as possible. You rarely to never want to return a wildcard generic from a method.
Sometimes this can lead to generic signatures:
This signature is both as specific and as general as possible
2) Yes, except possibly in some rare very specific cases (I'm thinking of
BitSet
, although that isn't technically aCollection
).如果您将列表声明为
List
,那么你可以传入任何静态类型为List
的对象,其中X extends A
ifA
是一个类,或者X 实现 A
idA
是一个接口。但是您将无法向其传递List
或List
但是,如果将参数声明为
List
,则只能传递静态类型与List
严格等效的列表,因此例如,不是
List
。我所说的“你不能这样做”,我真正的意思是“除非你强迫编译器关闭并接受它”,我认为除非处理遗留代码,否则不应该这样做。集合实际上是参考文献的集合。实际上,抽象是您可以放入变量中的所有内容都是对某些内容的引用,除非该变量是原始类型。
If you declare your list as
List<? extends A>
, then you can pass in any object which static type isList<X>
, whereX extends A
ifA
is a class, orX implements A
idA
is an interface. But you'll not be able to pass in aList
or aList<Object>
to it (unlessA
isObject
) without force-casting it.However, if you declare the parameter as a
List<A>
, you'll only be able to pass lists which static type is strictly equivalent toList<A>
, so notList<X>
for instance. And by "you are not able to do otherwise", I really mean "unless you force the compiler to shut up and accept it", which I believe one should not do unless dealing with legacy code.Collections are really collections of references. The abstraction actually is that everything you can put in a variable is a reference to something, unless that variable is of a primitive type.
1)我会推荐?扩展时间间隔。由于Java的多态性,它实际上可能没有什么区别,但它更健壮,风格更好
2) 是
1) I would recommend ? extends TimeInterval. Because of Java's polymorphism, it may not actually make a difference, but it is more robust and better style
2) Yes
a) 否。
列表
只接受扩展 TimeInterval 接口的接口。您的断言“您需要将列表创建为List
”是错误的,除非我误解了您的观点。这是一个示例:b) 是的。
a) No.
List<? extends TimeInterval>
will only accept interfaces that extend the interface TimeInterval. Your assertion that "you need to create your list as aList<TimeInterval>
is wrong, unless I misunderstand your point. Here's an example:b) Yes.
仅当您想传入
List
时才需要这样做。请注意,您可以将TimeInterval
子类的实例放入List
中。请记住,列表的类型与列表中的类型不同。如果你做
List myList
——这只影响您可以分配给myList
的内容,这与myList
中的内容不同。当您创建集合
Map myMap = new HashMap()
时,myMap
是对底层集合的引用。类似地,当您将某些内容放入集合中时,您将对基础对象的引用放入集合中。You only do that if you want to pass in a
List<TimeIntervalSubclass>
. Note you can put instances of subclasses ofTimeInterval
into aList<TimeInterval>
. Keep in mind that the type of the list is different than the types in the list.If you do
List<? extends A> myList
-- that only affects what you can assign tomyList
, which is different than what is inmyList
.When you create a collection
Map myMap = new HashMap()
,myMap
is a reference to the underlying collection. Similarly, when you put something into a collection, you are putting the reference to the underlying object into the collection.