Java接口集合

时间:2011-10-14 15:16:37

标签: java collections

我正在编写一个小API来处理具有特定“特征”的对象。在这种情况下,它们都有一个时间间隔和几个其他数据位,所以我用一些getter写了一个接口TimeInterval setter方法。

现在,大多数这些API方法都处理一组或一组对象。在内部,这些方法使用Java Colletions Framework(特别是HashMap / TreeMap)。所以这些API方法就像:

getSomeDataAboutIntervals(List<TimeInterval> intervalObjects);

几个问题:

a)这应该是List<? extends TimeInterval> intervalObjects吗?

这主要是风格问题吗?严格按照我可以看到的界面的一个缺点是,您需要将列表创建为List<TimeInterval>而不是List<ObjectThatImplementsTimeInterval>。 这意味着可能需要将List<Object..>复制到List<TimeInterval>以将其传递给API。

还有其他专业人士吗?两种方法都有缺点?

b)而且,一个愚蠢的问题:)集合框架保证我总是得到我放入的相同实例,集合实际上是一组引用,对吗?

5 个答案:

答案 0 :(得分:2)

1)是的。

方法参数应尽可能通用。 List<? extends A>List<A>更通用,可以在不需要向列表添加内容时使用。 如果您只是添加到列表中(而不是从中读取),则最常见的签名可能是List<? super A>

相反,方法返回类型应尽可能具体。您很少想永远不想从方法中返回通配符。

有时这会导致通用签名:

<T extends MyObject> List<T> filterMyObjects(List<T>)

此签名既具体又通用

2)是的,除了可能在一些罕见的非常具体的情况下(我正在考虑BitSet,尽管从技术上讲这不是Collection)。

答案 1 :(得分:1)

如果您将列表声明为List<? extends A>,那么您可以传入静态类型为List<X>的任何对象,X extends A如果A是类,或{ {1}} id X implements A是一个界面。但是,如果没有强行投射,您将无法传递AList(除非List<Object>A)。

但是,如果将参数声明为Object,则只能传递静态类型严格等同于List<A>的列表,因此不能传递List<A>。并且通过“你无法做到”,我的意思是“除非你强迫编译器闭嘴并接受它”,我认为除非处理遗留代码,否则不应该这样做。

集合实际上是引用的集合。抽象实际上是你可以放入变量的所有内容都是对某事物的引用,除非该变量属于基本类型。

答案 2 :(得分:1)

1)我会推荐?扩展TimeInterval。由于Java的多态性,它可能实际上没有区别,但它更健壮,风格更好

2)是的

答案 3 :(得分:0)

a)否。List<? extends TimeInterval>只接受扩展接口TimeInterval的接口。你的断言“你需要将你的列表创建为List<TimeInterval>是错误的,除非我误解了你的观点。这是一个例子:

List<List> mylist=  new ArrayList<List>();
mylist.add(new ArrayList());

b)是的。

答案 4 :(得分:0)

  

这应该是List intervalObjects吗?

如果您想传递List<TimeIntervalSubclass>,则只能这样做。请注意,您可以将TimeInterval的子类实例放入List<TimeInterval>。请注意,列表的类型与列表中的类型不同。

如果您执行List<? extends A> myList - 只影响您可以分配给myList的内容,这与 myList中的不同。

  

而且,一个愚蠢的问题:)集合框架保证我   总是拿出我放入的同一个实例,这些收藏品确实如此   一组参考文献,对吗?

创建集合Map myMap = new HashMap()时,myMap是对基础集合的引用。类似地,当您将某些内容放入集合时,您将对基础对象的引用放入集合中。