331

如果我有一个集合,例如Collection<String> strs,我怎样才能取出第一个项目?我可以打电话给 an Iterator,先拿走它next(),然后扔掉Iterator。有没有更浪费的方法呢?

4

14 回答 14

508

看起来这是最好的方法:

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

好问题……起初,这似乎是对Collection界面的疏忽。

请注意,“first”并不总是返回您放入集合中的第一件事,并且可能仅对有序集合有意义。也许这就是为什么没有get(item)调用的原因,因为不一定会保留订单。

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

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

请务必检查返回,iterator()因为它可能为空或null取决于实现。

于 2009-11-04T02:33:05.843 回答
140

Iterables.get(yourC, indexYouWant)

因为真的,如果你使用收藏,你应该使用谷歌收藏。

于 2009-11-04T03:09:11.317 回答
100

在 Java 8 中:

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

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

Iterables.getFirst(iterable, defaultValue)
于 2013-08-10T20:03:30.650 回答
42

a 中没有“第一个”项目这样的东西,Collection因为它只是一个集合。

从 Java 文档的Collection.iterator()方法:

无法保证返回元素的顺序...

所以你不能。

如果您使用其他接口,例如List,您可以执行以下操作:

String first = strs.get(0);

但是直接从一个集合中这是不可能的。

于 2009-11-04T02:26:38.820 回答
5

听起来您的 Collection 想要像 List 一样,所以我建议:

List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);
于 2009-11-04T02:34:30.817 回答
3

功能方式:

public static <T> Optional<T> findFirst(List<T> result) {
    return Optional.ofNullable(result)
            .map(List::stream)
            .flatMap(Stream::findFirst);
}

上面的代码片段保留从 NullPointerException 和 IndexOutOfBoundsException

于 2020-03-30T09:51:17.390 回答
2

在 Java 8 中,您可以使用许多运算符,例如limit

     /**
 * Operator that limit the total number of items emitted through the pipeline
 * Shall print
 * [1]
 * @throws InterruptedException
 */
@Test
public void limitStream() throws InterruptedException {
    List<Integer> list = Arrays.asList(1, 2, 3, 1, 4, 2, 3)
                               .stream()
                               .limit(1)
                               .collect(toList());
    System.out.println(list);
}
于 2016-07-11T08:18:47.170 回答
2

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

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

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

Optional<String> optionalString = collection.stream().findFirst();
于 2018-11-16T17:30:20.853 回答
1

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

Collection<String> getStrings();

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

List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));
于 2017-05-09T09:45:27.100 回答
0

如果您知道集合是一个队列,那么您可以将集合转换为队列并轻松获取它。

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

于 2009-11-04T02:33:30.267 回答
0

这完全取决于您使用的是哪个实现,是 arraylist 链表,还是 set 的其他实现。

如果设置了,那么您可以直接获取第一个元素,它们可以对集合进行特技循环,创建一个值为 1 的变量,并在标志值为 1 时获取值,然后打破该循环。

如果它是列表的实现,那么通过定义索引号很容易。

于 2015-10-28T10:12:07.313 回答
0

我用这个:

strs.isEmpty() ? "" : strs.iterator().next();

于 2021-12-01T09:32:01.223 回答
0

如果您使用的是 Apache Commons Collections 4,则有一种IterableUtils.first方法。它包含对Lists 的优化,并且使用起来很整洁。它与 Guava 方法非常相似。代码看起来像

String firstStr = IterableUtils.first(strs);
于 2022-02-07T16:18:10.050 回答
-3

你可以这样做:

String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];

Collection 的 javadoc 对数组元素的顺序给出了以下警告:

如果此集合对其迭代器返回其元素的顺序做出任何保证,则此方法必须以相同的顺序返回元素。

于 2009-11-04T02:32:07.383 回答