使用stream流能够更加优美,真正做到像写诗一样写代码。
为什么使用stream
- 可以更方便的操作集合
- 减少代码量
- 更加优雅
如何使用
基础使用
首先我们定义一个String集合或者数组,演示如何创建流:
java">// List集合
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
创建流很简单,使用.stream()方法即可创建,接下来我们添加几个人名到集合中:
java">// List集合
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
随后我们面临一个需求,需要找出对应姓的人,比如我要找出姓张的人,这个时候我们不借助流,实现的逻辑如下:
java">List<String> result = new ArrayList<>();
list.forEach(e->{
if (e.startsWith("张")){
result.add(e);
}
});
使用forEach,写个if判断能够实现效果,这个时候我们借助流的实现效果如下:
java">// 定义接收结果集
List<String> result = new ArrayList<>();
list.stream().filter(e -> e.startsWith("张")).forEach(e -> result.add(e));
// 更加简约的写法
List<String> resultList = list.stream().filter(e -> e.startsWith("张")).collect(Collectors.toList());
基本上一行就表达清楚了,而且与上面实现的效果一致,如果有多个过滤条件还可以继续使用.filter()方法进行叠加使用。
上面我们接触了流的filter()过滤器功能,还存在其他的使用方法:
-
limit(long maxSize)
获取集合前几个属性
java">// 初始化List集合 List<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); // 获取集合前2个属性,结果:张三 李四 List<String> collect = list.stream().limit(2).collect(Collectors.toList());
-
skip(long n)
跳过指定的前面几个元素
java">// 初始化List集合 List<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); // 跳过前面2个元素,结果:王五 List<String> collect = list.stream().skip(2).collect(Collectors.toList());
-
distinct()
元素去重
java">// 初始化List集合 List<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); // 增加一个重复元素 张三 list.add("张三"); // 去重处理,将重复元素[张三]剔除,结果:张三 李四 王五 List<String> collect = list.stream().distinct().collect(Collectors.toList());
-
sorted()
排序
java">// 初始化List集合 List<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); list.add("张三"); list.add("张三丰"); // 使用默认排序,结果:张三 张三 李四 王五 List<String> collect = list.stream().sorted().collect(Collectors.toList()); // 使用自定义排序,结果:诸葛孔明 张三丰 张三 李四 王五 张三 List<String> collect2 = list.stream().sorted(new Comparator<String>() { @Override public int compare(String o1, String o2) { // 根据名字长度倒序排序 return o2.length() - o1.length(); } }).collect(Collectors.toList());
-
allMatch(Predicate<? super T> predicate)
判断集合中是否有符合条件的属性
java">List<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); // 判断集合中是否有姓张的属性,结果:true boolean flagging = list.stream().allMatch(e -> e.startsWith("张"));
进阶使用
-
.stream().map()
映射
java">// 定义A类,包含两个构造函数,一个无参构造函数,另一个构造函数接收B类 class A{ private int id; private String name; public A(){ } public A(B b){ this.id = b.getId(); this.name = b.getName(); } } @Data class B{ private int id; private String name; } // 有一个A类集合 List<A> aList = new ArrayList<>(); aList.add(new A()); aList.add(new A()); aList.add(new A()); // 使用map进行映射 List<String> collect = aList.stream().map(B::new).collect(Collectors.toList());
-
排除list中的元素
java">List<String> listOne = new ArrayList<>(); listOne.add("张三"); listOne.add("李四"); listOne.add("王五"); List<String> listTwo = new ArrayList<>(); listTwo.add("张三"); listTwo.add("李四"); // 去除listOne中被listTwo包含的元素,结果:王五 List<String> resultList = listOne.stream().filter(o -> !listTwo.contains(o)).collect(Collectors.toList());
-
合并两个list,重复元素只保留一个
java">List<String> listOne = new ArrayList<>(); listOne.add("张三"); listOne.add("李四"); listOne.add("王五"); List<String> listTwo = new ArrayList<>(); listTwo.add("张三"); listTwo.add("李四"); List<String> resultList = Stream.of(listOne, listTwo).flatMap(Collection::stream).distinct().collect(Collectors.toList());
参考资料: