Java:从集合中获取第一个项目

Nic*_*ner 257 java collections iterable

如果我有一个收藏品,例如Collection<String> strs,我怎样才能获得第一件商品?我可以打电话给Iterator第一个next(),然后扔掉它Iterator.有没有浪费的方法吗?

jhe*_*ngs 410

看起来这是最好的方法:

String first = strs.iterator().next();
Run Code Online (Sandbox Code Playgroud)

很好的问题......起初,它似乎是对Collection界面的疏忽.

请注意,"first"并不总是返回您放入集合中的第一件事,并且可能仅对有序集合有意义.也许这就是为什么没有get(item)电话,因为订单不一定是坚持的.

虽然看起来有点浪费,但可能没有您想象的那么糟糕.该Iterator真的只是包含索引信息到集合,而不是通常的整个集合的副本.调用此方法会实例化Iterator对象,但这实际上是唯一的开销(而不是复制所有元素).

例如,查看ArrayList<String>.iterator()方法返回的类型,我们看到它是ArrayList::Itr.这是一个内部类,它只是直接访问列表的元素,而不是复制它们.

  • 奇怪的是,这不是公认的答案 (22认同)
  • 这应该是正确的答案.我不明白为什么答案总是"使用另一个库!" . (14认同)
  • 重要的是要注意,这个"技巧"仅在集合实际具有内容时才有效.如果它为空,则迭代器可能会返回错误,其中必须事先检查集合大小. (3认同)

Car*_*arl 126

Iterables.get(yourC,indexYouWant)

因为,如果您正在使用收藏集,那么您应该使用Google收藏集.

  • 它做同样的事情,它只检查它是否是一个列表,如果是,则通过索引获取.它还有一些代码可以尝试在实际Collection上更快地失败(也就是说,如果索引太大,它会尝试解决这个问题,而不会迭代整个事情并在最后抛出异常). (7认同)
  • 对于那些(仍然)到达这里的人:我认为jheddings的答案可能是最好的"完成它"的答案,尽管我更喜欢@DonaldRaab(在页面下方)我已经在使用GC库的情况.我的答案实际上是针对以下情况:人们可能希望稍后写出灵活性(例如,如果确定*second*元素是新的热点). (7认同)
  • 有时您只是在使用使用Collections的代码,因此没有太多要做。 (4认同)
  • 我当然同意它更干净,但OP很浪费,但我猜你的回答是被接受的,这是我想要的. (2认同)

Vit*_*nko 78

在java 8中:

Optional<String> firstElement = collection.stream().findFirst();
Run Code Online (Sandbox Code Playgroud)

对于旧版本的java,在Guava Iterables中有一个getFirst方法:

Iterables.getFirst(iterable, defaultValue)
Run Code Online (Sandbox Code Playgroud)

  • java 8解决方案特别有用,因为它可以优雅地处理集合为空的情况. (5认同)
  • 不好.你添加stream()的开销来得到get(0)只是因为你懒得编写4行代码.if(!CollectionUtils.isEmpty(productList)){return Optional.of(productList.get(0)); } return Optional.empty(); (4认同)
  • @RS如果你不能调用productList.get(0)会发生什么,因为它是一个Collection ..?(根据OP问题) (4认同)

Osc*_*Ryz 38

a中没有"第一"这样的东西,Collection因为它只是一个集合.

从Java doc的Collection.iterator()方法:

对于元素返回的顺序没有任何保证......

所以你不能.

如果使用其他界面(如List),则可以执行以下操作:

String first = strs.get(0);
Run Code Online (Sandbox Code Playgroud)

但直接来自Collection,这是不可能的.

  • 奥斯卡,我认为你夸大了这个案子.Collection的第一个元素在HashSet等少数情况下可能是任意的,但它定义明确:它是.iterator().next().它也是*稳定*,在我见过的每个集合实现中.(相关:请注意,虽然Set不保证顺序,但除了HashSet之外,JDK中Set的每个子类型都有.) (19认同)
  • 我不认为`get(int n)`是为`Collection`定义的 (11认同)
  • 它可能是,但考虑到在向集合中添加新元素时的情况,您不知道(通过接口)该元素是第一个,最后一个,还是将其插入到中间.要获得精确结果,您应该使用其他界面.然而,正如Rosarch所需要的那样,无论如何都是第一要素.了解底层收集可能会有所帮助,但它会阻止您更改它. (3认同)
  • 你是对的,我想念那一点.我已经更新了答案.你不能!(除非该集合由一些允许提供保证的底层类实现) (2认同)

Jim*_*ans 5

听起来你的收藏想要像列表一样,所以我建议:

List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);
Run Code Online (Sandbox Code Playgroud)