Stream使用技巧(1)------数据处理技巧
一. 背景
作为java8新特性之一的Stream API
为开发者带来了极大的便利,它可以对我们需要操作的集合进行非常复杂的操作,以活的我们想要的结果.
本文不会告诉你什么是Stream,毕竟网上花里胡哨的使用教程已经让我应接不暇,本系列博文只是记录一些Stream
的使用技巧,便于方便的查找和参考.
本博文会无限更新,有新的使用方法会逐渐添加进来,如果有小伙伴有新奇的使用技巧,也可以发出来一起分享.
本文中默认使用的对象user如下:
@Data
class User {
/** 名字 **/
private String name;
/** 年龄 **/
private Integer age;
/** 性别 true男false女 **/
private boolean sex;
User(String name, Integer age, boolean sex) {
this.age = age;
this.name = name;
this.sex = sex;
}
}
二. 使用案例
1. List<User>转Map<String, Integer>
-
需求描述:
有一个List集合,其中的每一个元素都是对象,想变成一个Map,其中key是对象的一个属性,value也是对象的一个属性或者对象本身.
-
伪代码:
@Test public void test1() { User a = new User("张三", 20, true); User b = new User("李四", 30, true); User c = new User("王五", 40, true); List<User> list = new ArrayList<User>(); list.add(a); list.add(b); list.add(c); //变成Map, key是name, value是age Map<String, Integer> collect = list.stream().collect(Collectors.toMap(User::getName, User::getAge)); System.out.println(collect); }
-
结果:
{李四=30, 张三=20, 王五=40}
2. List<User>转List<String>
-
需求描述:
List对象中,提取出每一个User对象的name属性,放在List里面
-
伪代码:
@Test public void test1() { User a = new User("张三", 20, true); User b = new User("李四", 30, true); User c = new User("王五", 40, true); List<User> list = new ArrayList<User>(); list.add(a); list.add(b); list.add(c); //取出每一个user的name变成list List<String> collect = list.stream().map(User::getName).collect(Collectors.toList()); System.out.println(collect); }
-
结果:
[张三, 李四, 王五]
3. List<User>转Map<Integer, Map<String, User>>
-
需求描述
用户集合中的用户,先按照年龄分组,再按照姓名分组,最终将用户分开
-
伪代码:
@Test public void test1() { User a = new User("张三", 20, true); User b = new User("李四", 30, true); User c = new User("王五", 40, true); User d = new User("花木兰", 40, false); User e = new User("李师师", 50, false); List<User> list = new ArrayList<User>(); list.add(a); list.add(b); list.add(c); list.add(d); list.add(e); //取出每一个user的name变成list Map<Integer, Map<String, User>> collect = list.stream().collect(Collectors.groupingBy( User::getAge, Collectors.toMap(User::getName, x -> x)) ); System.out.println(collect); }
-
结果:
{50={李师师=SampleStream.User(name=李师师, age=50, sex=false)}, 20={张三=SampleStream.User(name=张三, age=20, sex=true)}, 40={王五=SampleStream.User(name=王五, age=40, sex=true), 花木兰=SampleStream.User(name=花木兰, age=40, sex=false)}, 30={李四=SampleStream.User(name=李四, age=30, sex=true)}}
4. List<User>取出一个属性转List<Integer>, 并去重
-
需求描述
取出用户集合中的Age字段,放在一个List中,并去重
-
伪代码:
@Test public void test1() { User a = new User("张三", 20, true); User b = new User("李四", 30, true); User c = new User("王五", 40, true); User d = new User("花木兰", 40, false); User e = new User("李师师", 50, false); List<User> list = new ArrayList<User>(); list.add(a); list.add(b); list.add(c); list.add(d); list.add(e); //取出每一个user的name变成list List<Integer> collect = list.stream().map(User::getAge).distinct().collect(Collectors.toList()); System.out.println(collect); }
-
结果:
[20, 30, 40, 50]
5. List<User>去重并提出空值
-
需求描述
用户集合中有两个用户是相同的,且有个null对象,需要得到一个去重去空后的集合
-
伪代码:
@Test public void test1() { User a = new User("张三", 20, true); User b = new User("李四", 30, true); User c = new User("王五", 40, true); User d = new User("王五", 40, false); User e = new User("李师师", 50, false); List<User> list = new ArrayList<User>(); list.add(a); list.add(b); list.add(c); list.add(d); list.add(e); list.add(null); System.out.println("去重前: " + list); //取出每一个user的name变成list ArrayList<User> collect = list.stream().filter(Objects::nonNull).collect( Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new) ); System.out.println("去重后: " + collect); }
-
结果:
去重前: [SampleStream.User(name=张三, age=20, sex=true), SampleStream.User(name=李四, age=30, sex=true), SampleStream.User(name=王五, age=40, sex=true), SampleStream.User(name=王五, age=40, sex=false), SampleStream.User(name=李师师, age=50, sex=false), null] 去重后: [SampleStream.User(name=张三, age=20, sex=true), SampleStream.User(name=李四, age=30, sex=true), SampleStream.User(name=李师师, age=50, sex=false), SampleStream.User(name=王五, age=40, sex=true)]
结语:
在本篇博文中,列举了java8中Stream API在实际开发中的一些应用技巧,记录在这里,以后有需要的时候可以及时查阅
个人公众号<橙耘自留地>日前已经开通,后续博主发布的文章都会一并更新到公众号,如有需要,自行查阅.
关于橙耘自留地,是我个人聚焦互联网技术栈学习分享的一个平台,创立之初是因为目前业内各种技术课程资料层次不齐,褒贬不一,有时候一门课花费高价买入,其实内含草包,有时偶尔低价得之,却又大有干货.因此我会根据大家的意见和评价,选择不同的技术栈去学习,一为提升我自己的技术,二为大家梳理出质量比较好的课程,以作参考.同时,相关的学习心得也会一并更新到博客和公众号.