Java 通过谓词查找第一个元素
我刚刚开始使用Java8Lambdas,我正在尝试用函数式语言实现一些我习惯的东西 例如,大多数函数式语言都有某种对序列进行操作的find函数,或者返回谓词为Java 通过谓词查找第一个元素,java,java-8,java-stream,Java,Java 8,Java Stream,我刚刚开始使用Java8Lambdas,我正在尝试用函数式语言实现一些我习惯的东西 例如,大多数函数式语言都有某种对序列进行操作的find函数,或者返回谓词为true的第一个元素的列表。在Java 8中实现这一点的唯一方法是: lst.stream() .filter(x -> x > 5) .findFirst() 然而,这对我来说似乎效率低下,因为过滤器将扫描整个列表,至少在我看来是这样(这可能是错误的)。有更好的办法吗 否,过滤器不会扫描整个流。它是一个中间操
true
的第一个元素的列表。在Java 8中实现这一点的唯一方法是:
lst.stream()
.filter(x -> x > 5)
.findFirst()
然而,这对我来说似乎效率低下,因为过滤器将扫描整个列表,至少在我看来是这样(这可能是错误的)。有更好的办法吗 否,过滤器不会扫描整个流。它是一个中间操作,返回一个惰性流(实际上所有中间操作都返回一个惰性流)。要说服您,您只需执行以下测试:
List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
int a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.get();
System.out.println(a);
您可以看到,实际上只处理流的前两个元素
因此,您可以使用非常好的方法。不,过滤器不会扫描整个流。它是一个中间操作,返回一个惰性流(实际上所有中间操作都返回一个惰性流)。要说服您,您只需执行以下测试:
List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
int a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.get();
System.out.println(a);
您可以看到,实际上只处理流的前两个元素
所以你可以用你的方法,这是非常好的
然而,这对我来说似乎效率低下,因为过滤器将扫描整个列表
不,它不会-一旦找到满足谓词的第一个元素,它就会“中断”。你可以阅读更多关于懒惰的文章,特别是(我的重点):
许多流操作(如筛选、映射或重复删除)都可以延迟实现,从而提供了优化的机会。例如,“查找包含三个连续元音的第一个字符串”不需要检查所有输入字符串。流操作分为中间(产生流)操作和终端(产生价值或副作用)操作中间操作总是懒惰的。
然而,这对我来说似乎效率低下,因为过滤器将扫描整个列表
不,它不会-一旦找到满足谓词的第一个元素,它就会“中断”。你可以阅读更多关于懒惰的文章,特别是(我的重点):
许多流操作(如筛选、映射或重复删除)都可以延迟实现,从而提供了优化的机会。例如,“查找包含三个连续元音的第一个字符串”不需要检查所有输入字符串。流操作分为中间(产生流)操作和终端(产生价值或副作用)操作中间操作总是懒惰的。
我必须从对象列表中只筛选出一个对象。所以我用了这个,希望有帮助
我必须从对象列表中只筛选出一个对象。所以我使用了这个,希望它能有所帮助。除了用户的答案之外,如果您使用的是数组列表,您不确定要搜索的元素是否存在,请使用这个
Integer a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.orElse(null);
然后,您可以简单地检查a是否为null
,如果您使用的是数组列表,您不确定要搜索的元素是否存在,请使用此选项
Integer a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.orElse(null);
然后,您只需检查a是否为
null改进的一行回答:如果您要查找布尔返回值,我们可以通过添加isPresent来做得更好:
return dataSource.getParkingLots().stream().filter(parkingLot -> Objects.equals(parkingLot.getId(), id)).findFirst().isPresent();
改进的一行回答:如果您要查找布尔返回值,我们可以通过添加isPresent来做得更好:
return dataSource.getParkingLots().stream().filter(parkingLot -> Objects.equals(parkingLot.getId(), id)).findFirst().isPresent();
导入org.junit.Test;
导入java.util.array;
导入java.util.List;
导入java.util.Optional;
//对于相同的操作,流速度大约慢30倍。。。
公共类流性能测试{
int迭代次数=100;
List=Arrays.asList(1,10,3,7,5);
//55毫秒
@试验
公共空流(){
对于(int i=0;ix>5)
.findFirst();
System.out.println(result.orElse(null));
}
}
//2毫秒
@试验
公共void循环(){
对于(int i=0;i5){
结果=步行;
打破
}
}
系统输出打印项次(结果);
}
}
}
导入org.junit.Test;
导入java.util.array;
导入java.util.List;
导入java.util.Optional;
//对于相同的操作,流速度大约慢30倍。。。
公共类流性能测试{
int迭代次数=100;
List=Arrays.asList(1,10,3,7,5);
//55毫秒
@试验
公共空流(){
对于(int i=0;ix>5)
.findFirst();
System.out.println(result.orElse(null));
}
}
//2毫秒
@试验
公共void循环(){
对于(int i=0;i5){
结果=步行;
打破
}
}
系统输出打印项次(结果);
}
}
}
已由@AjaxLeung回答,但在评论中很难找到。
仅供检查
lst.stream()
.filter(x -> x > 5)
.findFirst()
.isPresent()
简化为
lst.stream()
.anyMatch(x -> x > 5)
已由@AjaxLeung回答,但在评论中很难找到。
仅供检查
lst.stream()
.filter(x -> x > 5)
.findFirst()
.isPresent()
简化为
lst.stream()
.anyMatch(x -> x > 5)
这不是低效的,Java8流实现是惰性的,所以过滤器只应用于终端操作。同样的问题:酷。这就是我希望它能做到的。那会是个少校