初始化测试数据
private List1.获取流对象strings = Arrays.asList("abc", "0", "bc", "for","bc", "e fg", "jse", "Ff", "jkl","886");
// 1. 获取串行流 Stream2.foreachstream = strings.stream(); // 2. 获取并行流 Stream stringStream = strings.parallelStream(); Collection list = new ArrayList<>(); // 多态 Stream s = list.stream(); Map map = new HashMap<>(); // 多态 // 获取键流 Stream keyStream = map.keySet().stream(); // map.keySet(): 获取键的集合 // 获取值流 Stream valueStream = map.values().stream(); // map.values(): 获取值的集合 // 获取键值对流 Stream > keyAndValueStream = map.entrySet().stream(); // map.entrySet(): 获取键值对的集合 String[] names = {"1", "2"}; // 1.1 数组获取流的方式 Stream namesStream = Arrays.stream(names); // 1.2 数组获取流的方式 Stream stringStream = Stream.of(names);
作用:遍历集合
// 遍历下 names 集合 names.forEach(System.out::println);3.collect
作用:收集器,能够将流转换为其他形式,比如:list set map
// 将 strings 集合转化成 set 集合 Set4.filteset = strings.stream().collect(Collectors.toSet()); // 将 strings 转换成 map 集合,key 为 prod_ + 集合中的值,value 为集合中的值 Map toMap = strings.stream().collect(Collectors.toMap(v -> "prod_" + v, v -> v, (oldValue, newValue) -> newValue)); // 将 student 集合按照 id(唯一) 封装成 map 集合 Map studentMap = students.stream().collect(Collectors.toMap(student -> student.getId().toString(), student -> student)); // 将 students 集合按照 年龄 封装成 map 集合 Map > studentListMap = students.stream().collect(Collectors.groupingBy(student -> String.valueOf(student.getAge())));
作用:用于通过设置的条件过滤出元素
// 将 strings 集合中带 f 的字符串筛选出来放如另外一个集合 List5.distinctfilterStrings = strings.stream().filter(str -> str.contains("f")).collect(Collectors.toList()); // 将 students 集合中年龄为 18 的同学找出来 List filterStudents = students.stream().filter(student -> 18 == student.getAge()).collect(Collectors.toList());
作用:去除集合中重复的元素
// 去除集合中重复的元素 List6.limitdistinct = strings.stream().distinct().collect(Collectors.toList());
作用:获取流中前 n 元素
//limit:获取流中前 n 元素 List7.skiplimitStrings = strings.stream().limit(2).collect(Collectors.toList());
作用:获取流中除去前 n 个元素的其它所有元素
//skip:获取流中除去前 n 个元素的其它所有元素 List8.mapskipNames = names.stream().skip(2).collect(Collectors.toList());
作用:用于映射每个元素到对应的结果
// 将集合 names 中的每个元素都拼接一个 A- str -A // 会将箭头函数处理出来的结果作为集合中的元素返回 List9.flatMapmapNames = names.stream().map( str -> "A-"+ str.concat("-A")).collect(Collectors.toList()); // 获取 students 集合中每个同学的 名字 List mapStudents = students.stream().map(Student::getName).collect(Collectors.toList());
作用:流的扁平化处理
flatMap:使用 flatMap 方法的效果是:各个数组并不是分别映射成一个流,而是映射成流的内容
所有使用 map(Arrays::stream) 时生成的单个流被合并起来,即扁平化为一个流
ListflatMap = strings.stream().flatMap(TestStream::getCharacterByString).collect(Collectors.toList()); List > map = strings.stream().map(TestStream::getCharacterByString).collect(Collectors.toList()); // 对比这 map 和 flatMap 两个方法 Stream > mapStream = strings.stream().map(TestStream::getCharacterByString); Stream flatMapStream = strings.stream().flatMap(TestStream::getCharacterByString); public static Stream getCharacterByString(String str) { List characterList = new ArrayList<>(); for (Character character : str.toCharArray()) { characterList.add(character); } return characterList.stream(); }
注意:
map 和 flatMap 的区别主要体现在返回对象中
map 的返回对象是 Stream
作用:转换类型
// 提取出 students 集合的 age 属性并转换成 Long 类型 List11.sortedmapToLongStudents = 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()//平均值
作用:用于对流进行排序
// 默认排序 List12.anyMatchdefaultSortedStrings = strings.stream().sorted().collect(Collectors.toList()); // 使用比较器 // 正向按中文排序 List collatorNames = names.stream().sorted(Collator.getInstance(Locale.CHINA)).collect(Collectors.toList()); // 反向按中文排序 List reverseOrderNames = names.stream().sorted(Collections.reverseOrder(Collator.getInstance(Locale.CHINA))).collect(Collectors.toList()); // 将 students 集合按照年龄进行排序,年龄相同则通过 id 进行排序 List collectStudents = students.stream().sorted(Comparator.comparing(Student::getAge).thenComparing(Student::getId)).collect(Collectors.toList());
作用:检查集合中是否至少匹配一个元素,返回 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
作用:将返回当前流中的任意元素
Optional16.findFirstany = strings.stream().findAny(); // 获取一下值,如果是 串行的流 默认会返回集合中的第一个(效率快) //if (any.isPresent()) System.out.println(any.get()); any.ifPresent(System.out::println); Optional any1 = strings.parallelStream().findAny(); // 获取一下值,如果是 并行的流 集合里的元素都有可能拿得到 any1.ifPresent(System.out::println);
作用:将返回集合中的第一元素
Optional17.reducefirst = names.stream().findFirst(); first.ifPresent(System.out::println);
作用:可以将流中元素反复结合起来,得到一个值
//identity = 默认值或初始值 //BinaryOperator = 函数式接口,取两个值并产生一个新值 T reduce(T identity, BinaryOperator18.countaccumulator); 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 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; }
作用:获取集合中元素的数量
// 查看 strings 集合中有多少元素 long count = strings.stream().count(); // 统计成绩大于 90 的分同学的个数 long countStudents = students.stream().filter(student -> (student.getScore() == null ? 0 : student.getScore()) > 90).count();19.peek
作用:接收一个没有返回值的λ表达式,可以做一些输出,外部处理等
// 将学生成绩为空的同学记上 0 分 返回 List20.Stream.ofpeekStudents = students.stream().filter(student -> student.getScore() == null).peek(student -> student.setScore(0)).collect(Collectors.toList());
作用:初始化集合
List21.concatlist = Stream.of("1", "2", "3").collect(Collectors.toList());
作用:合并流
Stream22.maxs1 = list.stream().filter(s -> s.startsWith("周")); Stream s2 = Stream.of("Java1", "Java2"); Stream s3 = Stream.concat(s1, s2); s3.forEach(s -> System.out.println(s));
//取最新时间 Optional23.分组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));
//按性别给用户分组 Map24.orElse 和 orElseGet> sexAndUserMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex)); //按性别分组统计名称List Map > sexAndNameListMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.mapping(User::getName, Collectors.toList()))); //按性别分组统计名称Set Map > sexAndNameSetMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.mapping(User::getName, Collectors.toSet()))); //按性别分组统计名称以及用户本身。 Map > sexAndNameAndDataMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.toMap(User::getName, data -> data))); //多级分组,按A属性分组,在此基础上按B属性分组 Map >> SexAndNameAndUserListMap = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.groupingBy(User::getName))); //遍历用户,构建一个名称与性别的Map映射关系 Map nameAndSexMap = users.parallelStream().collect(Collectors.toMap(User::getName, User::getSex));
- orElse(null)表示如果一个都没找到返回null
- orElseGet(null)表示如果一个都没找到返回null
- 区别就是在使用方法时,即时时没有值 也会执行 orElse 内的方法, 而 orElseGet则不会
@Test
public void test1(){
List list = new ArrayList();
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



