如果我有一个集合,如集合<String> strs,我怎么能得到第一项?我可以调用一个迭代器,取它的第一个next(),然后丢弃迭代器。有没有更少浪费的方法呢?


当前回答

在java 8中:

Optional<String> firstElement = collection.stream().findFirst();

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

Iterables.getFirst(iterable, defaultValue)

其他回答

如果你在使用Apache Commons Collections 4,有一个IterableUtils。第一个方法。在列表的情况下,它包含了一个优化,使用起来很整洁。这和番石榴法很相似。代码看起来像

String firstStr = IterableUtils.first(strs);

看起来这是最好的方法:

String first = strs.iterator().next();

好问题……起初,这似乎是Collection接口的一个疏忽。

请注意,“first”并不总是返回您放入集合中的第一个东西,并且可能只对有序集合有意义。也许这就是没有get(item)调用的原因,因为不一定要保留顺序。

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

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

只是要确保检查iterator()的返回值,因为它可能是空的或空的,这取决于实现。

Guava提供了一个onlyElement Collector,但只有在希望集合只有一个元素时才使用它。

Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())

如果不确定有多少元素,请使用findFirst。

Optional<String> optionalString = collection.stream().findFirst();

如果知道集合是队列,则可以将集合强制转换为队列并轻松获取它。

您可以使用几个结构来获得订单,但需要对其进行强制转换。

你可以选角。例如,如果存在一个具有此定义的方法,并且您知道该方法将返回一个List:

Collection<String> getStrings();

调用它之后,你需要第一个元素,你可以这样做:

List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));