【Java】Java8集合流的基本使用操作和场景

文章目录

        • 为什么使用流操作?
        • 常规业务场景
          • 准备对象
          • 1.想把对象集合中某个属性单独提取出来变成一个List<单独属性的类型>
          • 2.想根据对象集合中某个属性过滤一些数据
          • 3.将`1`和`2`进行合并
          • 4.将数据流进行分组
          • 5.将数据流由List变成Map的形式
          • 6.去掉数据流中重复的数据

为什么使用流操作?

最大原因是平时对一些集合进行操作,既有过滤,又有转换类型,又要收集等等…,曾经可能你的代码会是下面这种.

List<T> data = new ArrayList();

for(T t: data){
    //过滤逻辑
}

for(T t: data){
    //转换逻辑
}

for(T t: data){
    //收集等等
}

从上面的代码中可以看出,如果对集合有复杂操作的话,要for循环非常多次,而流操作只会执行一次。如果说常规只是简单处理,其实流操作跟普通forEach循环差不多。

常规业务场景
准备对象
@Data
public class Student{
    //学生名字
    private String name;
	//学生年龄
	private int age;
    //学生地址
    private String address;
	//学生所在班级
    private String className;
}
1.想把对象集合中某个属性单独提取出来变成一个List<单独属性的类型>

需求: 得到了一个List 对象集合,这时候想提取出里面的所有名字。

普通实现

//得到数据 这里直接先用new
List<Student> studentList = new ArrayList();
//先创建一个容器
List<String> nameList = new ArrayList()
for(Student student:studentList){
    nameList.add(student.getName());
}

流实现

//得到数据 这里直接先用new
List<Student> studentList = new ArrayList();
List<String> nameList =studentList.stream().map(x->x.getName()).collect(Collectors.toList());
2.想根据对象集合中某个属性过滤一些数据

需求: 得到一个List 对象集合,这时候我想过得到年龄大于18岁的学生。

普通实现

//得到数据 这里直接先用new
List<Student> studentList = new ArrayList();
//先创建一个容器
List<Student>  ageStudentList= new ArrayList()
for(Student student:studentList){
	//符合18岁
  	if(student.getAge()>18){
        ageStudentList.add(student);
    }
}

流实现

List<Student> ageStudentList =studentList.stream().filter(x->x.getAge()>18).collect(Collectors.toList());
3.将12进行合并

需求:得到一个List 对象集合,我想找到年龄大于18岁的学生,然后需要他们的名字集合

普通实现

//得到数据 这里直接先用new
List<Student> studentList = new ArrayList();
//先创建一个容器
List<Student>  ageStudentList= new ArrayList()
for(Student student:studentList){
	//符合18岁
  	if(student.getAge()>18){
        ageStudentList.add(student);
    }
}
List<String> nameStudentList = new ArrayList()
for(Student student: ageStudentList){
    nameStudentList.add(student.getName());
}

流实现

List<String> ageStudentList =studentList.stream().filter(x->x.getAge()>18).map(x->x.getName()).collect(Collectors.toList());

从这里是不是就可以看出流比较简洁,而且重申一遍,流只会一次forEach循环,数据量如果大的时候,就知道好处了!后续我就不再使用普通实现了,直接写流操作,大家以后写久了就习惯了,就那几种常用的写写,不常用的实在不行就百度。

4.将数据流进行分组

这也是一个非常常见的一种场景,尤其是从数据库中得到数据的时候需要进行分组一下。

需求: 根据学生班级将学生进行分组

流实现

//得到数据 这里直接先用new 
/*
    [
       {name:'张三',age:18,address:'北京',className:'1年级'},
       {name:'李四',age:15,address:'北京',className:'1年级'},
       {name:'王五',age:20,address:'北京',className:'2年级'},
    ]
*/
List<Student> studentList = new ArrayList();
//根据班级进行分组
Map<String, List<Student>> collect = studentList.stream().collect(Collectors.groupingBy(x->x.getClassName()));
//Map> collect = studentList.stream().collect(Collectors.groupingBy(Student::getClassName));
//最后这个Map的结果会是这样,我简单描绘一下,这个key就是年级,也就是你按什么分的组
{
    '1年级':[{name:'张三',age:18,address:'北京',className:'1年级'},{name:'李四',age:15,address:'北京',className:'1年级'}],
    '2年级':[{name:'王五',age:20,address:'北京',className:'2年级'}]
}
5.将数据流由List变成Map的形式

这个也非常常见,什么叫做List->Map,我先说一个业务场景,如果符合你就使用下面这个方式去解决。

/*
    [
       {name:'张三',age:18,address:'北京',className:'1年级'},
       {name:'李四',age:15,address:'北京',className:'2年级'},
       {name:'王五',age:20,address:'北京',className:'3年级'},
    ]
*/

说有一天领导跟你说,得到了上面这样的一个数据,他想变成一种映射关系,什么样的映射关系呢。<名字,学生对象> 这样的一个Map,便于后续的代码可以直接通过Map.getKey(名字)来获取指定的学生对象。注意:这里的前提是我们思维里已经知道这一堆数据那个要映射的key是唯一的,其实你4的场景熟练了这个也能解决,因为4的方案中可以得到<名字,List<学生对象>>,最后你getKey之后再get(0)就可以了。

流实现

studentList.stream().collect(Collectors.toMap(x->x.getName(),o->o));

现在具体说一下这个toMap

args1: 最终你要变成Map的key,你最后要拿到Map<名字,学生对象>,你的告诉人家你拿对象里面的什么属性做key吧

args2: 最终你要的value是什么,o->o的意思就是原来是啥就是啥我不做更换,因为我们就是要学生对象。

但是上面这种写法呢,是有一个问题的,这种写法是建立在绝对的key唯一的情况,就是你大脑是觉得这堆要处理的数据它一定是唯一的,key不能重复,如果重复,就嗝屁了

避免报错的一种写法

studentList.stream().collect(Collectors.toMap(x->x.getName(),o->o,(n1,n2)->n1));

args3:第三个参数说的就是万一遇到了key重复,你要怎么做呢,一般就是取其中一个咯,还能咋搞。

6.去掉数据流中重复的数据

需求:得到学生数据,假设年级一样的我认为就是一个数据,重复的我不想要。

/*
    [
       {name:'张三',age:18,address:'北京',className:'1年级'},
       {name:'李四',age:15,address:'北京',className:'1年级'},
       {name:'王五',age:20,address:'北京',className:'3年级'},
    ]
*/

以下这个写法记住就行,平时拿出来抄一抄就行了。

data = studentList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(x->x.getClassName()))), ArrayList::new));

你可能感兴趣的:(Java,java,jvm,数据结构)