Java8 stream 学习笔记

什么是stream

stream是Java8 中的一个新特性,它主要能让开发人员用函数式编程的方式(如Lamba表达式)对集合做聚合操作。所谓的聚合操作就是对集合的查找、遍历、过滤以及常见计算等。

下面是stream的一些常见操作介绍:

foreach:循环操作
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
map:将每一个元素映射到相应的结果里
List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
//get list of unique squares
List squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
filter:过滤某些元素
List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
//get list of unique squares
List squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
limit:限制输出流的个数
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
sorted:对输出流元素进行排序
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
Collectors:用于聚合输出流的结果,可拼成list或者string
Liststrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

System.out.println("Filtered List: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);

首先,我们创建一个存储了用户信息的列表进行示例,我们先看看如何过滤:

过滤出姓名为xiao ming的用户
User user1 = new User("xiao ming",  12, "小学");
User user2 = new User("mei mei", 18, "大学");
User user3 = new User("li lei", 11, "小学");
User user4 = new User("xiao hong",  15, "初中");

List userList = new ArrayList<>(3);
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);

useList.stream().filter(user -> user.getName().equals("xiao ming")).forEach(user -> System.out.println(user.getGrade()));

你可以看到只要在列表后加上.stream(),默认就会生成一个流。
有了这个流后,你可以调用filter(),并在里边设置过滤条件即可过滤出相应的元素

下面我们再看看基于stream转成其他数据结构,现在我们将这个User类转成另外一个类。
原User类
class User{
    String name;
    int age;
    String grade;
}
异构后的类
class UserInfo{
     String name;
     int age;
     String extend;
}

如果按传统写法,我们肯定就要用for循环遍历原userlist,再一个个赋值过去了,现在有了stream就只需这样:

List userInfoList = userList.stream.map(tmp->{
                 UserInfo = usrInfo = new UserInfo();
                 usrInfo.setName(tmp.getName());
                 usrInfo.setAge(tmp.getAge());
                 if (tmp.getGrade().equals("大学")){
                       usrInfo.setExtend("university");  
                }
                return usrInfo;
         }).collect(Collectors.toList());

再换个玩法,如果希望list转成map,key为用户名,value为整个用户对象,最后遍历打印map里的对象,那用stream要怎么玩呢?

Map userMap = userList.stream().collect(Collectors.toMap(User::getName, user -> user));
userMap.forEach((K, V) -> System.out.println("key:" + K + "val:" + V));

好,我们继续加需求,在原User类上,要记录他所借阅过的书籍,那么数据结构将会变成这样:

原User类
class User{
    String name;
    int age;
    String grade;
    Set books;

    public void addBook(String book) {
        if (this.book == null) {
            this.book = new HashSet<>();
        }
        this.book.add(book);
    }
}

我们要将小明,梅梅借的书读取出来

//初始化
User user1 = new User("xiao ming",  12, "小学");
User user2 = new User("mei mei", 18, "大学");

//添加图书
user1.addBook("Java 8 in Action");
user1.addBook("Spring Boot in Action");
user1.addBook("Effective Java (2nd Edition)");

user2.addBook("Learning Python, 5th Edition");
user2.addBook("Effective Java (2nd Edition)");

List userList = new ArrayList<>(3);
userList.add(user1);
userList.add(user2);

List collect = list.stream()
                        .map(x -> x.getBook())      //Stream>
                        .flatMap(x -> x.stream())   //Stream
                        .distinct()
                        .collect(Collectors.toList());

collect.forEach(x -> System.out.println(x));
按照年级对用户进行分组
Map> userGroup = userList.stream().collect(Collectors.groupingBy(User::getGrade));
判断用户列表中是否有符合指定年龄段的用户

boolean isAllAdult = useList.stream().allMatch(p -> p.getAge() > 10);
boolean isAnyChild = useList.stream().anyMatch(p -> p.getAge() < 12);

引用来源

  1. https://mkyong.com/java8/java-8-flatmap-example/
  2. https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
  3. https://stackoverflow.com/questions/26684562/whats-the-difference-between-map-and-flatmap-methods-in-java-8

你可能感兴趣的:(Java8 stream 学习笔记)