我刚刚开始使用Java 8 lambdas,我正在尝试实现一些我在函数式语言中习惯的东西。
例如,大多数函数式语言都有某种find函数,它对序列或列表进行操作,返回谓词为真的第一个元素。我认为在Java 8中实现这一目标的唯一方法是:
lst.stream()
.filter(x -> x > 5)
.findFirst()
然而,这似乎对我来说效率很低,因为过滤器会扫描整个列表,至少在我的理解(这可能是错误的)。有没有更好的办法?
我刚刚开始使用Java 8 lambdas,我正在尝试实现一些我在函数式语言中习惯的东西。
例如,大多数函数式语言都有某种find函数,它对序列或列表进行操作,返回谓词为真的第一个元素。我认为在Java 8中实现这一目标的唯一方法是:
lst.stream()
.filter(x -> x > 5)
.findFirst()
然而,这似乎对我来说效率很低,因为过滤器会扫描整个列表,至少在我的理解(这可能是错误的)。有没有更好的办法?
当前回答
return dataSource.getParkingLots()
.stream()
.filter(parkingLot -> Objects.equals(parkingLot.getId(), id))
.findFirst()
.orElse(null);
我必须从对象列表中只过滤出一个对象。所以我用了这个,希望能有所帮助。
其他回答
对于我来说,一个带有循环的通用实用函数似乎要干净得多:
static public <T> T find(List<T> elements, Predicate<T> p) {
for (T item : elements) if (p.test(item)) return item;
return null;
}
static public <T> T find(T[] elements, Predicate<T> p) {
for (T item : elements) if (p.test(item)) return item;
return null;
}
在使用:
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);
Integer[] intArr = new Integer[]{1, 2, 3, 4, 5};
System.out.println(find(intList, i -> i % 2 == 0)); // 2
System.out.println(find(intArr, i -> i % 2 != 0)); // 1
System.out.println(find(intList, i -> i > 5)); // null
改进的一行回答:如果你正在寻找一个布尔返回值,我们可以通过添加isPresent来做得更好:
return dataSource.getParkingLots().stream().filter(parkingLot -> Objects.equals(parkingLot.getId(), id)).findFirst().isPresent();
除了Alexis C的回答,如果你正在使用一个数组列表,你不确定你正在搜索的元素是否存在,使用这个。
Integer a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.orElse(null);
然后你可以简单地检查a是否为空。
@AjaxLeung已经回复了,但在评论中很难找到。 仅供支票使用
lst.stream()
.filter(x -> x > 5)
.findFirst()
.isPresent()
化简为
lst.stream()
.anyMatch(x -> x > 5)
return dataSource.getParkingLots()
.stream()
.filter(parkingLot -> Objects.equals(parkingLot.getId(), id))
.findFirst()
.orElse(null);
我必须从对象列表中只过滤出一个对象。所以我用了这个,希望能有所帮助。