Stream学习的特点
Stream流的创建
可以通过集合创建流,也可以通过Stream.of()方法直接创建流。例如:List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); Stream<String> stream = names.stream();
中间操作
中间操作允许对流进行各种转换和处理,例如过滤、映射、排序等。常见的中间操作包括filter、map、sorted等。
终端操作
终端操作是对流进行最终操作,触发流(中间操作)的处理。
常见的终端操作包括forEach、collect、reduce等。
Stream特点
惰性求值
Stream的操作通常是惰性求值的,只有在遇到终端操作时才会触发中间操作的执行。
并行处理
Stream API支持并行处理,可以通过parallel()方法将流转换为并行流,以提高处理大量数据时的效率。
函数式编程
Stream API借鉴了函数式编程的思想,可以通过Lambda表达式来传递操作
IDEA编辑器:记得光标浮在Stream代码附近:按一下Alt + Enter IDEA会自动帮我们做转换为循环,方便我们理解代码,也可以在For循环附件,帮我们转为Stream的代码
Java8提供了常用函数式接口
函数式接口就是我们常用的lambda表达式的内容。
- Function<T,R> 转换型:接受一个输入参数,返回一个结果
- Consumer<T> 消费型:接受一个输入参数,无返回
- Predicate<T> 判断型:接受一个输入参数,返回Boolean结果
- Supplier<T> 供给型:无参数,返回结果
函数式接口的应用
Stream流使用案例
我们先添加一个Pojo作为我们操作的对象 UserInfo
添加一个实体,方便我们模拟真实集合去测试方法。
@Data
public class UserInfo {
private Integer id;
private String name;
private Integer isDelete;
public UserInfo(Integer id, String name, Integer isDelete) {
this.id = id;
this.name = name;
this.isDelete = isDelete;
}
}
List -> Map
注意,如果List集合元素有重复,Map是不允许重复的,就需要考虑去重问题。
public static void main(String[] args) {
ArrayList<UserInfo> list = new ArrayList();
list.add(new UserInfo(1, "张三", 1));
list.add(new UserInfo(2, "李四", 2));
list.add(new UserInfo(3, "王五", 3));
list.add(new UserInfo(3, "赵六", 4));
Map<Integer, UserInfo> userInfoMap = list.stream().collect(
Collectors.toMap(
(UserInfo::getId), (userInfo -> userInfo), (k1, k2) -> {
if (k1.getIsDelete() > k2.getIsDelete()) {
return k1;
} else {
return k2;
}
})
);
userInfoMap.values().forEach(k -> {
System.out.println(String.format("name=%s,isDelete=%s",k.getName(),k.getIsDelete()));
});
Filter 过滤元素
.filter
方法 对集合或Stream中的元素进行过滤,只保留满足特定条件的元素。
接受一个Predicate作为参数,该Predicate定义了过滤的条件。
public static void main(String[] args) {
ArrayList<UserInfo> list = new ArrayList();
list.add(new UserInfo(1, "张三", 1));
list.add(new UserInfo(2, "李四", 2));
list.add(new UserInfo(3, "王五", 3));
list.add(new UserInfo(3, "赵六", 4));
List<UserInfo> collect = list.stream()
.filter(userInfo -> userInfo.getIsDelete() > 2)
.collect(Collectors.toList());
collect.forEach(k -> {
System.out.println(String.format("name=%s,isDelete=%s", k.getName(), k.getIsDelete()));
});
LinkedList<Integer> collect1 = collect.stream()
.map(UserInfo::getId)
.collect(Collectors.toCollection(LinkedList::new));
System.out.println("获取到的ID列表是" + collect1);
}
GroupingBy分组
我们日常SQL使用的时候,都是Group By实现分组。Stream也有类似功能,比如一个集合有3个组的员工,我们想获取每个组的员工,就可以通过.collect(Collectors.groupingBy(Obj::getXXX));实现。返回的集合是Map集合!
public static void main(String[] args) {
ArrayList<UserInfo> list = new ArrayList();
list.add(new UserInfo(1, "张三", 1));
list.add(new UserInfo(2, "李四", 2));
list.add(new UserInfo(3, "王五", 3));
list.add(new UserInfo(3, "赵六", 4));
Map<Integer, List<UserInfo>> collect = list.stream()
.collect(Collectors.groupingBy(UserInfo::getId));
collect.forEach((k,v) -> {
System.out.println(String.format("GroupID=%s,Element=%s",k.toString(),Arrays.toString(v.toArray())));
});
}
统计数量
collect(Collectors.groupingBy(UserInfo::getId, Collectors.counting()));
排序 sorted + Comparator
原对象不会发生变更,新对象才会排序。
public static void main(String[] args) {
ArrayList<UserInfo> list = new ArrayList();
list.add(new UserInfo(1, "张三", 1));
list.add(new UserInfo(2, "李四", 2));
list.add(new UserInfo(3, "王五", 3));
list.add(new UserInfo(3, "赵六", 4));
List<UserInfo> collect = list.stream()
.sorted(Comparator
.comparing(UserInfo::getId)
.thenComparing(UserInfo::getIsDelete, Comparator.reverseOrder())
)
.collect(Collectors.toList());
collect.forEach(k -> {
System.out.println(String.format("id=%s,name=%s,isDelete=%s", k.getId(), k.getName(), k.getIsDelete()));
});
}
时间格式对比
workList.sort((o1, o2) -> {
LocalDateTime dateTime1 = parseDateTime(o1.getDispatchTime());
LocalDateTime dateTime2 = parseDateTime(o2.getDispatchTime());
return dateTime2.compareTo(dateTime1);
});
private static LocalDateTime parseDateTime(String dateTimeStr) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.parse(dateTimeStr, formatter);
} catch (Exception e) {
log.error("日期解析失败: {}", dateTimeStr);
return LocalDateTime.MIN;
}
}
Distinct 对集合元素去重
public static void main(String[] args) {
ArrayList<String> list = new ArrayList();
list.add("A");
list.add("A");
list.add("B");
list.add("A");
List<String> collect = list.stream().distinct().collect(Collectors.toList());
collect.forEach(k -> {
System.out.println(String.format("Element=%s",k));
});
}
FindFirst 返回第一个元素
还没有评论,来说两句吧...