2024最全大厂面试题无需C币点我下载或者在网页打开全套面试题已打包
AI绘画关于SD,MJ,GPT,SDXL百科全书
-
使用
filter
方法过滤掉null
值:List<String> nonNullElements = stream.filter(Objects::nonNull).collect(Collectors.toList());
这种方法会移除流中的所有
null
元素。 -
使用
Optional
类来处理可能为null
的值:List<String> nonNullElements = stream.map(element -> Optional.ofNullable(element).orElse("default")) .collect(Collectors.toList());
这种方法会将流中的每个元素包装在
Optional
中,如果元素为null
,则使用orElse
方法提供的默认值。 -
使用
Stream.ofNullable
方法:List<String> nonNullElements = Stream.ofNullable(element).collect(Collectors.toList());
这种方法会创建一个包含单个元素的流,如果元素为
null
,则流为空。 -
使用
Stream.filter
结合Objects::nonNull
:List<String> nonNullElements = stream.filter(Objects::nonNull).collect(Collectors.toList());
这种方法与第一种方法相同,会移除流中的所有
null
元素。 -
使用
Stream.flatMap
结合Optional
:List<String> nonNullElements = stream.flatMap(element -> Optional.ofNullable(element).stream()) .collect(Collectors.toList());
这种方法会将流中的每个元素转换为
Optional
,然后将Optional
中的元素(如果存在)转换为流,最后将这些流扁平化为一个流。 -
使用
Stream.peek
方法:List<String> nonNullElements = stream.peek(element -> { if (element == null) { throw new IllegalArgumentException("Null elements are not allowed"); } }).collect(Collectors.toList());
这种方法会在流的每个元素上执行一个操作,如果元素为
null
,则抛出异常。 -
使用
Stream.map
结合Objects::requireNonNull
:List<String> nonNullElements = stream.map(element -> Objects.requireNonNull(element, "Element cannot be null")) .collect(Collectors.toList());
这种方法会检查每个元素是否为
null
,如果是,则抛出NullPointerException
。
请注意,这些方法中的大多数都是在处理流中的元素时避免null
值,而不是在创建流时避免null
值。如果你需要在创建流时避免null
值,你可能需要在流的源头进行检查,或者使用Optional
来包装可能为null
的值。
在Java的Stream API中,peek
方法用于对流中的每个元素执行一个操作,但不会影响流的元素。peek
方法通常用于调试目的,比如打印流中的元素或者执行一些副作用操作。
如果你在peek
方法中抛出异常,这将导致流的处理中断。这是因为peek
方法中的异常会传播到调用栈中,如果在流的中间操作中抛出异常,流的处理将停止,后续的流操作(如collect
、forEach
等)将不会被执行。
例如:
List<String> list = Arrays.asList("a", "b", null, "c");
list.stream()
.peek(element -> {
if (element == null) {
throw new IllegalArgumentException("Null elements are not allowed");
}
})
.forEach(System.out::println); // 这行代码将不会被执行,因为peek中的异常会中断流
在这个例子中,当流处理到null
元素时,peek
方法会抛出IllegalArgumentException
,这将导致流的处理中断,因此forEach
方法中的System.out::println
将不会被执行。
需要注意的是,尽管peek
方法可以用于执行副作用操作,但通常不推荐在peek
中抛出异常,因为这可能会导致流的处理中断,而且这种做法并不符合流操作的声明式风格。如果你需要处理可能为null
的元素,应该使用filter
方法来过滤掉null
值,或者使用Optional
来包装可能为null
的值,而不是在peek
中抛出异常。
filter
和 peek
是 Java Stream API 中的两个不同的中间操作,它们在流处理中的作用和目的有所不同:
-
filter:
filter
方法用于筛选流中的元素,它接受一个谓词(Predicate)作为参数,该谓词定义了哪些元素应该被保留。filter
方法会返回一个新的流,其中只包含满足谓词条件的元素。filter
是一个无状态操作,它不会改变流中的元素,只是根据条件选择元素。filter
通常用于移除不需要的元素,比如过滤掉空值或不符合条件的数据。
示例:
List<String> list = Arrays.asList("a", "b", null, "c"); List<String> nonNullElements = list.stream() .filter(Objects::nonNull) .collect(Collectors.toList());
-
peek:
peek
方法用于对流中的每个元素执行一个操作,但不会影响流的元素。peek
方法通常用于调试目的,比如打印流中的元素或者执行一些副作用操作。peek
是一个无状态操作,它不会改变流中的元素,只是对每个元素执行一个操作。peek
通常不用于改变流中的元素,而是用于观察流中的元素或者执行一些额外的操作。
示例:
List<String> list = Arrays.asList("a", "b", "c"); list.stream() .peek(System.out::println) // 打印每个元素 .collect(Collectors.toList());
filter
用于筛选流中的元素,而 peek
用于对流中的每个元素执行一个操作。filter
会返回一个新的流,其中只包含满足条件的元素,而 peek
不会改变流中的元素,只是对每个元素执行一个操作。在实际使用中,filter
用于数据处理,而 peek
用于调试或执行副作用操作。