ava 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
先创建测试对象
package com.example.springboot.Entity; import lombok.*; import java.util.ArrayList; import java.util.List; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class Author implements Comparable<Author>{ private int id; private String name; private int age; /** * 书籍列表 */ private List<Book> bookList; public static List<Author> getAuthers() { Author a1 = Author.builder().id(1).name("张三").age(20).build(); Book b1 = Book.builder().id(100).name("倾城之恋").build(); Book b2 = Book.builder().id(200).name("挪威的森林").build(); List<Book> list1 = new ArrayList<Book>(){}; list1.add(b1); list1.add(b2); a1.setBookList(list1); Author a2 = Author.builder().id(2).name("阿凡达").age(22).build(); Author a3 = Author.builder().id(3).name("李冰冰").age(33).build(); Author a4 = Author.builder().id(4).name("肉丝").age(34).build(); Book b3 = Book.builder().id(300).name("红楼梦").build(); List<Book> list3 = new ArrayList<Book>(){}; list3.add(b1); list3.add(b3); a3.setBookList(list3); Author a5 = Author.builder().id(5).name("老刘").age(35).build(); Author a6 = Author.builder().id(6).name("大张").age(55).build(); List<Author> arrList = new ArrayList<>(); arrList.add(a1); arrList.add(a2); arrList.add(a3); arrList.add(a4); arrList.add(a5); arrList.add(a6); return arrList; } /** * 自己实现Comparable接口 * @param o 排序对象 * @return 对比值 */ @Override public int compareTo(Author o) { return o.getAge() - this.getAge(); } /** * 重写equals,ID一样就是相同数据 * @param obj 对比数据 * @return 是否为同一条数据 */ public boolean equals(Object obj) { //判断内存地址 if (obj == this) { return true; } if (obj == null) { return false; } //判断是否是同一类型的对象 if (obj instanceof Author) { //强制转换成Person类型 Author per = (Author) obj; //判断他们的属性值 注:这里的age为什么要用==?可以在评论区回答 if (this.id == per.id) { return true; } } return false; } }
测试对象
package com.example.springboot.Entity; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class Book { private int id; private String name; /** * 作者 */ private int autId; public static List<Book> getBookList(){ Book b1 = Book.builder().id(1).name("倾城之恋").autId(1).build(); Book b2 = Book.builder().id(2).name("荆棘鸟").autId(1).build(); Book b3 = Book.builder().id(3).name("挪威的森林").autId(2).build(); Book b4 = Book.builder().id(4).name("红楼梦").autId(3).build(); List<Book> arrList = new ArrayList<>(); arrList.add(b1); arrList.add(b2); arrList.add(b3); arrList.add(b4); return arrList; } /** * 重写equals,ID一样就是相同数据 * @param obj 对比数据 * @return 是否为同一条数据 */ public boolean equals(Object obj) { //判断内存地址 if (obj == this) { return true; } if (obj == null) { return false; } //判断是否是同一类型的对象 if (obj instanceof Book) { //强制转换成Person类型 Book per = (Book) obj; //判断他们的属性值 注:这里的age为什么要用==?可以在评论区回答 if (this.id == per.id) { return true; } } return false; } }
测试代码
package com.example.springboot; import com.alibaba.fastjson.JSON; import com.example.springboot.Entity.Author; import com.example.springboot.Entity.Book; import org.junit.jupiter.api.Test; import java.util.*; import java.util.stream.Collectors; public class StreamTest { /** * findAny 随机 找到 一个 数据 * findFirst 找到 第一个 数据 */ @Test public void testFindAny(){ Optional<Author> optionalAuthor = Author.getAuthers().stream() .distinct() .filter(author -> author.getAge() >= 35) .findFirst(); // .findAny(); optionalAuthor.ifPresent(author -> System.out.println(author)); } /** * anyMatch 流中数据是否有 一个 匹配数据 * allMatch 流中数据必须 全部 匹配 * noneMatch 流中数据 没有 匹配 */ @Test public void testMatch(){ boolean isHava = Author.getAuthers().stream() .distinct() .noneMatch(author -> author.getAge() >= 35); // .allMatch(author -> author.getAge() >= 35); // .anyMatch(author -> author.getAge() >= 35); System.out.println("是否找到数据:" + isHava); } /** * max 计算流中元素最大值,min类似 */ @Test public void testMax(){ Optional<Integer> max = Author.getAuthers().stream() .distinct() .map(author -> author.getAge()) // Idea会提示替换为下面写法 // .max((age1, age2) -> age1 - age2); .max(Comparator.comparingInt(age -> age)); System.out.println(max.get()); } /** * count 统计流中元素个数 */ @Test public void testCount(){ long count = Author.getAuthers().stream() .distinct() .count(); System.out.println("共有数据:" + count); } /** * reduce 将流中数据按照规则计算出一个结果 */ @Test public void testReduce(){ int re = Author.getAuthers().stream() .distinct() .map(author -> author.getAge()) // 计算作者年龄 总和,参数0是初始值 .reduce(0, (age1, age2) -> age1 + age2); System.out.println("年龄总和:" + re); re = Author.getAuthers().stream() .distinct() .map(author -> author.getAge()) // 计算作者年龄 最大,参数0是初始值 .reduce(0, (age1, age2) -> age1 > age2 ? age1 : age2); System.out.println("年龄最大:" + re); Optional<Integer> optionalInteger = Author.getAuthers().stream() .distinct() .map(author -> author.getAge()) // 计算作者年龄 最小,一个参数没有初始值 .reduce((age1, age2) -> age1 > age2 ? age2 : age1); System.out.println("年龄最小:" + optionalInteger.get()); } /** * sorted 将流中数据按照规则排序 */ @Test public void testSorted(){ Author.getAuthers().stream() // 使用对象实现的compareTo方法 // .sorted() // 使用Lambda编写逻辑 // .sorted((aut1, aut2) -> aut1.getAge() - aut2.getAge()) // 使用提供的工具,reversed()降序 .sorted(Comparator.comparingInt(Author::getAge).reversed()) // 跳过一个后取前三个 .skip(1) .limit(3) .forEach(author -> System.out.println(author)); } /** * collect 将流转换为一个Set */ @Test public void testCollectToSet() { Set<Author> authorsSet = Author.getAuthers().stream() .collect(Collectors.toSet()); System.out.println(JSON.toJSONString(authorsSet, true)); } /** * collect 将流转换为一个Map */ @Test public void testCollectToMap() { Map<Integer, Author> autMap = Author.getAuthers().stream() // 先去重,否则有重复对象时报错 .distinct() // 这里指定以作者ID为Key,以作者对象为Value .collect(Collectors.toMap(Author::getId, author -> author)); System.out.println(JSON.toJSONString(autMap, true)); // 如果按指定规则收集时,会有多个结果,就使用分组,指定分组规则 Map<Integer, List<Book>> bookMap = Book.getBookList().stream() // 一个作者会写多本书 .collect(Collectors.groupingBy(Book::getAutId)); System.out.println(JSON.toJSONString(bookMap, true)); } /** * collect 将流转换为一个List */ @Test public void testCollectToList() { List<String> autNameList = Author.getAuthers().stream() .map(author -> author.getName()) .collect(Collectors.toList()); System.out.println(JSON.toJSONString(autNameList)); } /** * flatMap 返回流,该流将包含通过映射函数替换源流的每个元素而获得的元素,并展平结果 * distinct 通过equals方法判断是否为同一个对象,所以,可以重写Object的方法来定制 */ @Test public void testFlatMap() { Author.getAuthers().stream() // 注意这里依然要做为空判断 .flatMap(author -> null == author.getBookList() ? null : author.getBookList().stream()) .distinct() .forEach(book -> System.out.println(book)); } /** * map 将流中对象进行转换 */ @Test public void testMap() { Author.getAuthers().stream() // 这里Map操作后返回的流里面都是String .map(author -> author.getName()) .forEach(name -> System.out.println(name)); } /** * filter 过滤流中数据 */ @Test public void testFilter() { Author.getAuthers().stream() // 可以添加多个过滤条件 .filter(author -> author.getAge() >= 35) .filter(author -> author.getName().length() >= 2) .forEach(author -> System.out.println(author)); } /** * forEach 遍历流中数据 */ @Test public void testForEach() { Author.getAuthers().stream() .forEach(author -> System.out.println(author)); } }
END
Java小强
未曾清贫难成人,不经打击老天真。
自古英雄出炼狱,从来富贵入凡尘。
发表评论: