【问题标题】:Get last not null element of list by using Java 8使用 Java 8 获取列表的最后一个非空元素
【发布时间】:2015-09-18 12:49:58
【问题描述】:

在 Java 7 中,如果我想获取列表的最后一个非空元素,我会这样写:

public CustomObject getLastObject(List<CustomObject> list) {
    for (int index = list.size() - 1; index > 0; index--) {
        if (list.get(index) != null) {
            return list.get(index);
        }
    }
    // handling of case when all elements are null
    // or list is empty
    ...
}

我想使用 lambdas 或 Java 8 的其他功能编写更短的代码。例如,如果我想获取第一个非空元素,我可以这样写:

public void someMethod(List<CustomObject> list) {
    .....
    CustomObject object = getFirstObject(list).orElseGet(/*handle this case*/);
    .....
}

public Optional<CustomObject> getFirstObject(List<CustomObject> list) {
    return list.stream().filter(object -> object != null).findFirst();
}

也许有人知道如何解决这个问题?

【问题讨论】:

标签: java lambda java-8 java-stream


【解决方案1】:

一种可能的解决方案是以相反的顺序遍历 List 并保留第一个非 null 元素:

public Optional<CustomObject> getLastObject(List<CustomObject> list) {
    return IntStream.range(0, list.size()).mapToObj(i -> list.get(list.size() - i - 1))
                                          .filter(Objects::nonNull)
                                          .findFirst();
}

请注意,Stream API 中没有 findLast 方法,因为 Stream 不一定是有序的或有限的。

另一种解决方案是遍历列表并通过仅保留当前元素来减少它。这有效地将 Stream 减少到最后一个元素。

public Optional<CustomObject> getLastObject(List<CustomObject> list) {
    return list.stream().filter(Objects::nonNull).reduce((a, b) -> b);
}

【讨论】:

  • @assylias Collection.stream() 返回的流是连续的(根据 Javadoc)
  • 这就是为什么我链接到其他问题,以表明这一点,例如使用reduce 获取最后一个元素is an established solution。它甚至可以并行执行。归约函数必须是关联的,但不需要是可交换的。
猜你喜欢
  • 2018-08-17
  • 2011-12-28
  • 2019-08-11
  • 1970-01-01
  • 2010-10-30
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多