Java8特性----lambda表达式之Collection常见操作

现在越来越多的公司开始使用jdk8了,jdk8有许多新特性,其中一个特性便是流式处理,进而有好多对于集合的便利操作

我自己也是刚开始熟悉jdk8,便在此记录一些基本的关于集合的操作 至于一些理论上的东西我就不写了,某度一大堆,因为一点点介绍每段的含义来路也不是一篇博客就能写完的,我只会简单说一下每段的意思,废话不多说,上代码

先创建一下的练习会用到的类

    

package com.chunying.lambda;

/**
 * @author chunying
 */
public class Student {
    private final String name;
    private final Integer age;
    private final Gender gender;

    public Student(String name, Integer age , Gender gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public Gender getGender() {
        return gender;
    }

    public enum Gender{MALE , FEMALE};
}
package com.chunying.lambda;

import java.util.Arrays;
import java.util.List;

/**
 * @author chunying
 */
public class LambdaDemo {

    List<Student> data = Arrays.asList(
            new Student("张三" ,23 , Student.Gender.MALE),
            new Student("李四" ,24 , Student.Gender.MALE),
            new Student("王五" ,24 , Student.Gender.FEMALE),
            new Student("赵六" ,23 , Student.Gender.FEMALE)
    );
}

这里我创建了一个学生类以及学生类的集合,以下的所有操作都将通过它们来完成

首先第一个:获取所有男性的学生集合

如果没有jdk8我们会怎样写呢?

@Test
public void fun1() {
    //所有男性集合
    List<Student> result = new ArrayList<>();

    for(Student student : data) {
        if(student.getGender().equals(Student.Gender.MALE)) {
            result.add(student);
        }
    }
    System.out.println(result);
}

需要遍历集合,一个一个去判断是否符合我们的条件,如果数据量比较大,或者判断条件比较多,那么可能在单线程情况下就会比较慢。多线程:就要和synchronized打交道,烦不胜烦,一不注意没处理好就会出问题

jdk8帮我们解决了这个问题

我们先看代码

@Test
public void fun2() {
    List<Student> result = data.stream()
                               .filter(student -> student.getGender().equals(Student.Gender.MALE))
                               .collect(Collectors.toList());

    System.out.println(result);
}

首先lambda表达式的基础我就不说了,我会在其他文章补充,这里不是重点,这个结果和上面是一样的

首先stream()方法,将集合变成了流,

fileter()方法,过滤到我们所需要的,

最后collect(Collectors.toList())将得到的流对象转换为集合。

第二个:将所有的学生按照年纪分组,并且获取到所有的年纪的集合

首先还是看没有jdk8怎么做

@Test
public void fun3() {
    List<Integer> allAges = new ArrayList<>();
    Map<Integer , List<Student>> studentByAge = new HashMap<>();

    for(Student student : data) {
        Integer age = student.getAge();
        if(!allAges.contains(age)) {
            allAges.add(age);
        }
        List<Student> temp = studentByAge.get(age);
        if(temp == null) {
            temp = new ArrayList<>();
            temp.add(student);
            studentByAge.put(age , temp);
        }else {
            temp.add(student);
        }
    }

    System.out.println(allAges);
    System.out.println(studentByAge);
}

其中temp集合是完全没有用的中间计算集合。非常麻烦而且不易读

我们看jdk8怎么做

@Test
public void fun4() {
    List<Integer> allAges = data.stream().map(Student::getAge)
                                         .distinct()
                                         .collect(Collectors.toList());
    Map<Integer , List<Student>> studentByAge = data.stream().collect(Collectors.groupingBy(Student::getAge));
    System.out.println(allAges);
    System.out.println(studentByAge);
}

先看获取年纪,通过map()方法获取到所有的年纪,distinct()去重,collect转换成集合

分组这边,比较上面这里仅仅一行代码,通过groupingBy()把所有的学生按照年纪分组即可。

第三个:所有学生按照姓名分组(假设没有重名的)

首先还是看没有jdk8怎么做。

@Test
public void fun5() {
    Map<String , Student> studentByName = new HashMap<>();
    for(Student student : data) {
        studentByName.put(student.getName() , student);
    }
}

接下来看jdk8

@Test
public void fun6() {
    Map<String , Student> studentByName = data.stream().collect(Collectors.toMap(Student::getName , student->student));
}

这里用到了toMap()方法,不多解释了

第四个:集合遍历

jdk8之前集合遍历,单列集合都可以通过for(Object o : data){}来遍历,底层无非还是iterator。

map就麻烦了,一种是通过拿到keySet再去拿每一个值,一种是通过entrySet拿到每一个entry对象,再去获取键值。操作很不方便 

直接看jdk8的结合遍历

@Test
public void fun6() {
    Map<String , Student> studentByName = data.stream().collect(Collectors.toMap(Student::getName , student->student));

    data.forEach(student -> {
        System.out.println(student);
    });

    studentByName.forEach((name , student)-> {
        System.out.println(name + "-" + student);
    });

}
怎么样是不是方便了很多?

第五个:排序以及类型转换

jdk8以前的排序大多是通过Comparator来排序,每次要定义排序规则或者比较器,很不方便

我们看jdk8

@Test
public void fun7() {
    //将所有学生按照年级排序并返回学生集合
    List<Student> result = data.stream()
                               .sorted(Comparator.comparing(Student::getAge))
                               .collect(Collectors.toList());
    System.out.println(result);
}

是不是很方便的。

常用的操作就这些,我就先记录到这里。



猜你喜欢

转载自blog.csdn.net/java_ying/article/details/81031973