Java8Stream

Java8Stream,第1张

初始化测试数据

  private List<String> strings = Arrays.asList("abc", "0", "bc", "for","bc", "e fg", "jse", "Ff", "jkl","886");
 
1.获取流对象
  // 1. 获取串行流
  Stream<String> stream = strings.stream();

  // 2. 获取并行流
  Stream<String> stringStream = strings.parallelStream();

   /*------------------Collection集合获取流--------------------*/
   Collection<String> list = new ArrayList<>();  // 多态
   Stream<String> s = list.stream();

   /*------------------Map集合获取流--------------------*/
   Map<Integer, String> map = new HashMap<>();  // 多态

   // 获取键流
   Stream<Integer> keyStream = map.keySet().stream();  //  map.keySet(): 获取键的集合

   // 获取值流
   Stream<String> valueStream = map.values().stream();  //  map.values(): 获取值的集合

   // 获取键值对流
   Stream<Map.Entry<Integer, String>> keyAndValueStream = map.entrySet().stream();  // map.entrySet(): 获取键值对的集合

   /*------------------数组获取流--------------------*/
   String[] names = {"1", "2"};
   // 1.1 数组获取流的方式
   Stream<String> namesStream = Arrays.stream(names);
   // 1.2 数组获取流的方式
   Stream<String> stringStream = Stream.of(names);
2.foreach

作用:遍历集合

 // 遍历下 names 集合
 names.forEach(System.out::println);
3.collect

作用:收集器,能够将流转换为其他形式,比如:list set map

  // 将 strings 集合转化成 set 集合
  Set<String> set = strings.stream().collect(Collectors.toSet());
  
  // 将 strings 转换成 map 集合,key 为 prod_ + 集合中的值,value 为集合中的值
  /**
   *   v -> "prod_" + v                              key
   *   v -> v                                        value
   *   (oldValue, newValue) -> newValue              遇到重复的选 newValue
   */
  Map<String, String> toMap = strings.stream().collect(Collectors.toMap(v -> "prod_" + v, v -> v, (oldValue, newValue) -> newValue));

  // 将 student 集合按照 id(唯一) 封装成 map 集合
  Map<String, Student> studentMap = students.stream().collect(Collectors.toMap(student -> student.getId().toString(), student -> student));

  // 将 students 集合按照 年龄 封装成 map 集合
  Map<String, List<Student>> studentListMap = students.stream().collect(Collectors.groupingBy(student -> String.valueOf(student.getAge())));
        
4.filte

作用:用于通过设置的条件过滤出元素

  // 将 strings 集合中带 f 的字符串筛选出来放如另外一个集合
  List<String> filterStrings = strings.stream().filter(str -> str.contains("f")).collect(Collectors.toList());

  // 将 students 集合中年龄为 18 的同学找出来
  List<Student> filterStudents = students.stream().filter(student -> 18 == student.getAge()).collect(Collectors.toList());

5.distinct

作用:去除集合中重复的元素

  // 去除集合中重复的元素
  List<String> distinct = strings.stream().distinct().collect(Collectors.toList());
6.limit

作用:获取流中前 n 元素

  //limit:获取流中前 n 元素
  List<String> limitStrings = strings.stream().limit(2).collect(Collectors.toList());
7.skip

作用:获取流中除去前 n 个元素的其它所有元素

  //skip:获取流中除去前 n 个元素的其它所有元素
  List<String> skipNames = names.stream().skip(2).collect(Collectors.toList());

8.map

作用:用于映射每个元素到对应的结果

  // 将集合 names 中的每个元素都拼接一个 A- str -A
  // 会将箭头函数处理出来的结果作为集合中的元素返回
  List<String> mapNames = names.stream().map( str -> "A-"+ str.concat("-A")).collect(Collectors.toList());
  // 获取 students 集合中每个同学的 名字
  List<String> mapStudents = students.stream().map(Student::getName).collect(Collectors.toList());
9.flatMap

作用:流的扁平化处理

flatMap:使用 flatMap 方法的效果是:各个数组并不是分别映射成一个流,而是映射成流的内容
所有使用 map(Arrays::stream) 时生成的单个流被合并起来,即扁平化为一个流

  List<Character> flatMap = strings.stream().flatMap(TestStream::getCharacterByString).collect(Collectors.toList());
  
  List<Stream<Character>> map = strings.stream().map(TestStream::getCharacterByString).collect(Collectors.toList());

  // 对比这 map 和 flatMap 两个方法
  /**
   * map 解析:
   *      1) [a,b,c] , [0] ,..., [8,8,6]
   *      2) [a,b,c,0,b,c,...,8,8,6]
   * flatMap 解析:
   *      1) [a,b,c] , [0] ,..., [8,8,6]
   *
   * map 是返回一个值,而 flatMap 返回一个流,多个值
   */
  Stream<Stream<Character>> mapStream = strings.stream().map(TestStream::getCharacterByString);

  Stream<Character> flatMapStream = strings.stream().flatMap(TestStream::getCharacterByString);

 /**
   * 字符串转换为字符流
   */
  public static Stream<Character> getCharacterByString(String str) {
      List<Character> characterList = new ArrayList<>();
      for (Character character : str.toCharArray()) {
          characterList.add(character);
      }
      return characterList.stream();
  }

注意:
map 和 flatMap 的区别主要体现在返回对象中
map 的返回对象是 Stream,而 flatMap 返回的对象是 Stream

10.mapToXxx

作用:转换类型

  // 提取出 students 集合的 age 属性并转换成 Long 类型
  List<Long> mapToLongStudents = students.stream().mapToLong(Student::getAge).boxed().collect(Collectors.toList());

  //list.stream().mapToDouble求最⼤、最⼩、和、平均值
  list.stream().mapToDouble(User::getAge).sum()//和
  list.stream().mapToDouble(User::getAge).max()//最⼤
  list.stream().mapToDouble(User::getAge).min()//最⼩
  list.stream().mapToDouble(User::getAge).average()//平均值
11.sorted

作用:用于对流进行排序

  // 默认排序
  List<String> defaultSortedStrings = strings.stream().sorted().collect(Collectors.toList());
  
  // 使用比较器
  // 正向按中文排序
  List<String> collatorNames = names.stream().sorted(Collator.getInstance(Locale.CHINA)).collect(Collectors.toList());
  // 反向按中文排序
  List<String> reverseOrderNames = names.stream().sorted(Collections.reverseOrder(Collator.getInstance(Locale.CHINA))).collect(Collectors.toList());

  // 将 students 集合按照年龄进行排序,年龄相同则通过 id 进行排序
  List<Student> collectStudents = students.stream().sorted(Comparator.comparing(Student::getAge).thenComparing(Student::getId)).collect(Collectors.toList());
  
12.anyMatch

作用:检查集合中是否至少匹配一个元素,返回 true

  boolean anyMatchBcStrings = strings.stream().anyMatch(s -> s.contains("bc"));
13.allMatch

作用:检查是否匹配所有元素,返回 true

  boolean result = ints.stream().allMatch(s -> s>0);
14.noneMatch

作用:检查是否没有匹配所有元素,返回 true

 boolean result = strings.stream().noneMatch(s -> s.length()<5);
15.findAny

作用:将返回当前流中的任意元素

  Optional<String> any = strings.stream().findAny();
  // 获取一下值,如果是 串行的流 默认会返回集合中的第一个(效率快)
  //if (any.isPresent()) System.out.println(any.get());
  any.ifPresent(System.out::println);

  Optional<String> any1 = strings.parallelStream().findAny();
  // 获取一下值,如果是 并行的流 集合里的元素都有可能拿得到
  any1.ifPresent(System.out::println);
16.findFirst

作用:将返回集合中的第一元素

  Optional<String> first = names.stream().findFirst();
  first.ifPresent(System.out::println);
17.reduce

作用:可以将流中元素反复结合起来,得到一个值

  //identity = 默认值或初始值
  //BinaryOperator = 函数式接口,取两个值并产生一个新值
  T reduce(T identity, BinaryOperator<T> accumulator);
  
  int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
  
  //第一种方式求和
  int sum = Arrays.stream(numbers).reduce(0, (a, b) -> a + b);
  System.out.println("sum : " + sum); // 55
 
  //第二种方式求和
  int sum = Arrays.stream(numbers).reduce(0, Integer::sum); // 55
  
  //数学运算
  int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
  int sum = Arrays.stream(numbers).reduce(0, (a, b) -> a + b);    // 55
  int sum2 = Arrays.stream(numbers).reduce(0, Integer::sum);      // 55
 
  int sum3 = Arrays.stream(numbers).reduce(0, (a, b) -> a - b);   // -55
  int sum4 = Arrays.stream(numbers).reduce(0, (a, b) -> a * b);   // 0, initial is 0, 0 * whatever = 0
  int sum5 = Arrays.stream(numbers).reduce(0, (a, b) -> a / b);   // 0

  //最大和最小
  int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
  int max = Arrays.stream(numbers).reduce(0, (a, b) -> a > b ? a : b);  // 10
  int max1 = Arrays.stream(numbers).reduce(0, Integer::max);            // 10
 
  int min = Arrays.stream(numbers).reduce(0, (a, b) -> a < b ? a : b);  // 0
  int min1 = Arrays.stream(numbers).reduce(0, Integer::min);            // 0

  //连接字符串
  String[] strings = {"a", "b", "c", "d", "e"};
 
  // |a|b|c|d|e , the initial | join is not what we want
  String reduce = Arrays.stream(strings).reduce("", (a, b) -> a + "|" + b);
 
  // a|b|c|d|e, filter the initial "" empty string
  String reduce2 = Arrays.stream(strings).reduce("", (a, b) -> {
      if (!"".equals(a)) {
          return a + "|" + b;
      } else {
          return b;
      }
  });
 
  // a|b|c|d|e , better uses the Java 8 String.join :)  (最好使用 Java 8 的 String.join)
  String join = String.join("|", strings);

  //Map & Reduce
  // 发票集合
  List<Invoice> invoices = Arrays.asList(
          new Invoice("A01", BigDecimal.valueOf(9.99), BigDecimal.valueOf(1)),
          new Invoice("A02", BigDecimal.valueOf(19.99), BigDecimal.valueOf(1.5)),
          new Invoice("A03", BigDecimal.valueOf(4.99), BigDecimal.valueOf(2))
  );

  BigDecimal sum = invoices.stream()
          .map(x -> x.getQty().multiply(x.getPrice()))    // map,对集合中的元素进行 *** 作
          .reduce(BigDecimal.ZERO, BigDecimal::add);      // reduce,将上一步得到的结果进行合并得到最终的结果
  System.out.println(sum);    // 49.955
  System.out.println(sum.setScale(2, RoundingMode.HALF_UP));  // 49.96 使用setScale方法进行四舍五入
  //输出
  //49.955
  //49.96
  class Invoice {
    // 发票号码
    String invoiceNo;
    // 价格
    BigDecimal price;
    // 数量
    BigDecimal qty;
  }
18.count

作用:获取集合中元素的数量

 // 查看 strings 集合中有多少元素
 long count = strings.stream().count();

 // 统计成绩大于 90 的分同学的个数
 long countStudents = students.stream().filter(student -> (student.getScore() == null ? 0 : student.getScore()) > 90).count();
19.peek

作用:接收一个没有返回值的λ表达式,可以做一些输出,外部处理等

 // 将学生成绩为空的同学记上 0 分 返回
 List<Student> peekStudents = students.stream().filter(student -> student.getScore() == null).peek(student -> student.setScore(0)).collect(Collectors.toList());
20.Stream.of

作用:初始化集合

  List<String> list = Stream.of("1", "2", "3").collect(Collectors.toList());
21.concat

作用:合并流

  Stream<String> s1 = list.stream().filter(s -> s.startsWith("周"));
  Stream<String> s2 = Stream.of("Java1", "Java2");
  Stream<String> s3 = Stream.concat(s1, s2);
  s3.forEach(s -> System.out.println(s));

22.max
//取最新时间
Optional<Date> maxDate = list.stream()
.max((p1,p2) -> p1.getDate().compareTo(p2.getDate()))
.map(object -> object.getDate());
Date date = maxDate.get();

Employee oneMax = one.stream().max((o1, o2) -> Double.compare(o1.getBonus() + o1.getSalary(), o2.getSalary() + o2.getBonus())).get();
System.out.println(oneMax);

Topperformer oneTopperformer = one.stream().max((o1, o2) -> Double.compare(o1.getBonus() + o1.getSalary(), o2.getSalary() + o2.getBonus())).map(
        employee -> new Topperformer(employee.getName(), employee.getBonus() + employee.getSalary())
).get();
System.out.println(oneTopperformer);

one.stream().sorted((o1, o2) -> Double.compare(o1.getBonus() + o1.getSalary(), o2.getSalary() + o2.getBonus())).  // 升序
        skip(1).limit(one.size()-2).forEach(employee -> {
            allMoney += (employee.getBonus() + employee.getSalary());
});
System.out.println("部门1的平均工资为:" + allMoney / (one.size() - 2));
23.分组
  //按性别给用户分组
  Map<String, List<User>> sexAndUserMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex));

  //按性别分组统计名称List
  Map<String, List<String>> sexAndNameListMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.mapping(User::getName, Collectors.toList())));

  //按性别分组统计名称Set
  Map<String, Set<String>> sexAndNameSetMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.mapping(User::getName, Collectors.toSet())));

  //按性别分组统计名称以及用户本身。
  Map<String, Map<String, User>> sexAndNameAndDataMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.toMap(User::getName, data -> data)));

  //多级分组,按A属性分组,在此基础上按B属性分组
  Map<String, Map<String, List<User>>> SexAndNameAndUserListMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.groupingBy(User::getName)));

  //遍历用户,构建一个名称与性别的Map映射关系
  Map<String, String> nameAndSexMap = users.parallelStream().collect(Collectors.toMap(User::getName, User::getSex));
24.orElse 和 orElseGet
  • orElse(null)表示如果一个都没找到返回null
  • orElseGet(null)表示如果一个都没找到返回null
  • 区别就是在使用方法时,即时时没有值 也会执行 orElse 内的方法, 而 orElseGet则不会
@Test
public void test1(){
    List<Integer> list =  new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    Integer a =  list.stream().filter(v->v==2).findFirst().orElse(get("a"));
    Integer b =  list.stream().filter(v->v==2).findFirst().orElseGet(()->get("b"));
       System.out.println("a  "+a);
       System.out.println("b  "+b);
   }
   public static int get(String name){
       System.out.println(name+"执行了方法");
       return 1;
   }
//输出
//a执行了方法
//a  2
//b  2

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/872100.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存