流处理
相信大家肯定遇到过列表需要按某个字符进行排序, 这时我们用流处理就可以很优雅的实现该功能了
convert.setItems(convert.getItems().stream()
.sorted(Comparator.comparing(
item -> StringUtils.defaultIfBlank(item.getWarehouseName(), ""),
Collator.getInstance(Locale.CHINESE)
))
.collect(Collectors.toList()));
解释
-
StringUtils.defaultIfBlank
:StringUtils.defaultIfBlank(item.getWarehouseName(), "")
会返回item.getWarehouseName()
如果它不是空或null
,否则返回空字符串""
。
-
Comparator.comparing
:Comparator.comparing
方法用于创建一个比较器,这里使用Collator.getInstance(Locale.CHINESE)
来确保中文字符的正确排序。
-
collect(Collectors.toList())
:- 将排序后的流收集为一个新的列表,并设置回
convert
对象的items
属性。
- 将排序后的流收集为一个新的列表,并设置回
或者在列表中对手机号进行加密等操作
// 手机号加密
List<GetPackageListRes.GetPackageListInnerPackage> items = convert.getItems().stream()
.peek(item -> item.setSenderMobile(StringUtils.isBlank(item.getSenderMobile()) ? "" : AppAesUtils.aesEncrypt(item.getSenderMobile())))
.collect(Collectors.toList());
在Java 8的Stream API中,peek
和 map
是两个常用的中间操作方法,它们的功能和用途有所不同。下面是它们的区别和用法示例:
peek
方法
用途
peek
主要用于调试目的,它允许你在流的处理过程中打印或检查每个元素,而不改变元素本身。peek
不会对流中的元素进行任何转换或修改,它只是提供了一个钩子,让你可以在流的处理过程中插入一些操作(通常是日志记录或断言)。
方法签名
Stream<T> peek(Consumer<? super T> action)
示例
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = numbers.stream()
.peek(System.out::println) // 打印每个元素
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(result); // 输出: [2, 4]
在这个示例中,peek
用于打印流中的每个元素,但不会改变它们。最终的结果是 [2, 4]
。
map
方法
用途
map
用于将流中的每个元素转换为另一个形式。它接受一个函数作为参数,并将该函数应用于流中的每个元素,生成一个新的流。map
是一种转换操作,它可以改变流中元素的类型或值。
方法签名
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
示例
List<String> words = Arrays.asList("apple", "banana", "cherry");
List<Integer> lengths = words.stream()
.map(String::length) // 将每个字符串转换为其长度
.collect(Collectors.toList());
System.out.println(lengths); // 输出: [5, 6, 6]
在这个示例中,map
将每个字符串转换为其长度,生成一个新的流,最终的结果是 [5, 6, 6]
。
总结
-
peek
:- 用于调试,不改变流中的元素。
- 主要用于在流的处理过程中插入一些操作,如打印日志。
- 返回类型与输入类型相同。
-
map
:- 用于转换,可以改变流中的元素。
- 接受一个函数作为参数,将该函数应用于流中的每个元素。
- 返回类型可以与输入类型不同。
示例对比
假设我们有一个列表,包含一些 GetSelfPickupAddressesListRes
对象,我们希望在处理过程中打印每个对象,并根据 selfPickupType
修改 receiverAddr
。
使用 peek
和 map
List<GetSelfPickupAddressesListRes> listRes = ...; // 初始化列表
List<GetSelfPickupAddressesListRes> processedListRes = listRes.stream()
.peek(res -> System.out.println("Processing: " + res))
.map(res -> {
if (GetSelfPickupAddressesListRes.SELF_PICKUP_TYPE_CABINET.equals(res.getSelfPickupType())) {
res.setReceiverAddr(res.getReceiverAddr() + "(自提柜)");
} else if (GetSelfPickupAddressesListRes.SELF_PICKUP_TYPE_POINT.equals(res.getSelfPickupType())) {
res.setReceiverAddr(res.getReceiverAddr() + "(自提点)");
}
return res;
})
.collect(Collectors.toList());
// 打印处理后的结果
processedListRes.forEach(System.out::println);
在这个示例中:
peek
用于在处理每个对象时打印一条消息。map
用于根据selfPickupType
修改receiverAddr
。
通过这种方式,你可以同时使用 peek
进行调试,并使用 map
进行转换。
Optional常见用法
在日常项目开发中, 我们少不了对应信息进行脱敏加密, 如果对应信息从服务调用而来, 这时我们就需要对信息进行判空处理。
在Java 8中,Optional
类提供了一种处理可能为 null
的值的优雅方式。filter
和 map
方法是 Optional
类中非常有用的两个方法,它们分别用于过滤和转换值。下面是对这两个方法的详细解释和示例。
filter
方法
用途
filter
方法用于根据给定的谓词(Predicate
)来决定是否保留Optional
中的值。- 如果谓词返回
true
,则Optional
中的值保持不变;如果谓词返回false
,则Optional
变为Optional.empty()
。
方法签名
Optional<T> filter(Predicate<? super T> predicate)
示例
Optional<String> optionalValue = Optional.of("1234567890");
Optional<String> filteredValue = optionalValue.filter(s -> s.length() > 5);
System.out.println(filteredValue.orElse("Default Value")); // 输出: 1234567890
在这个示例中,filter
方法检查字符串的长度是否大于5。因为 "1234567890"
的长度是10,所以 filteredValue
仍然是 Optional.of("1234567890")
。
map
方法
用途
map
方法用于将Optional
中的值转换为另一种类型。- 它接受一个函数(
Function
),并将该函数应用于Optional
中的值,生成一个新的Optional
。
方法签名
<U> Optional<U> map(Function<? super T, ? extends U> mapper)
示例
Optional<String> optionalValue = Optional.of("1234567890");
Optional<Integer> mappedValue = optionalValue.map(s -> s.length());
System.out.println(mappedValue.orElse(0)); // 输出: 10
在这个示例中,map
方法将字符串转换为其长度,生成一个新的 Optional<Integer>
。
综合示例
结合 filter
和 map
方法,我们可以更优雅地处理可能为 null
或空字符串的情况,并进行转换。
dto.setReceiverFixtel(
Optional.ofNullable(res.getReceiverFixtel())
.filter(StringUtils::isNotBlank)
.map(CommonUtil::overlayPhone)
.orElse("")
);
解释
-
Optional.ofNullable(res.getReceiverFixtel())
:- 创建一个
Optional
对象,如果res.getReceiverFixtel()
返回null
,则Optional
为Optional.empty()
。
- 创建一个
-
.filter(StringUtils::isNotBlank)
:- 使用
filter
方法检查Optional
中的值是否不是空字符串。如果值是空字符串或null
,则Optional
变为Optional.empty()
。
- 使用
-
.map(CommonUtil::overlayPhone)
:- 使用
map
方法将Optional
中的值转换为电话号码的遮罩形式。CommonUtil::overlayPhone
是一个静态方法,假设它接受一个字符串并返回一个遮罩后的字符串。
- 使用
-
.orElse("")
:- 如果
Optional
为Optional.empty()
,则返回默认值""
。否则,返回转换后的值。
- 如果
再举个例子,对值进行判空后类型转换:
Optional<String> length = Optional.ofNullable(waybillBaseDto.getLength()).map(String::valueOf);
Optional<String> width = Optional.ofNullable(waybillBaseDto.getWidth()).map(String::valueOf);
Optional<String> height = Optional.ofNullable(waybillBaseDto.getHeight()).map(String::valueOf);