本文主要给大家讲解Java8中最重要的一个特征之一lambda表达式,本文通过实例图文解说给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习下吧
目录
一:什么是 Stream?
二:Stream API 使用
1:使用Stream步骤:
2:创建Stream的方法的4种方式
3:中间操作
4:终止操作
Java 8新特性----Stream流
jdk8是Java 语言开发的一个主要版本,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等等。今天就重点介绍一个非常重要得特性之一 lambda表达式
一:什么是 Stream?
Java中的Stream并不会存储元素,而是按需计算。 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
聚合操作 类似sql语句一样的操作, 比如filter, map, reduce, find, match, sorted等。 和以前的Collection操作不同,Stream操作还有两个基础的特征如下:
Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格。 这样做可以对操作进行优化, 比如延迟执行和短路。
内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫>做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
二:Stream API 使用
1:使用Stream步骤:
(2)中间链式操作 一个中间的操作链,对数据源的数据进行处理。
注意:Stream操作是延迟执行,他们会等需要结果的时候才会执行。
中间操作常用方法有:筛选:filter 映射:map 排序:sorted提取与组合 收集:collect。
终止操作:遍历:foreach 匹配:find、match 规约:reduce 聚合:max、min、count。
2:创建Stream的方法的4种方式
【1】Collection接口中的方法: default Stream stream() 获取串行流 default Stream parallelStream() 获取并行流 案例:
//方式1:Collection接口的方法 Collection collection = new ArrayList(); Stream stream = collection.stream(); Stream stream1 = collection.parallelStream(); //方式2:通过Arrays中的Stream方法 数组 IntStream stream2 = Arrays.stream(new int[]{1, 2, 3, 4, 5}); //方式3:Stream中的of方法 Stream stream3 = Stream.of("111", "222", "333"); //方法4:Stream中的方法 创建无限流 (结果是无线个) Stream iterate = Stream.iterate(2, (x) -> x + 2);
3:中间操作
1:筛选与切片
① Stream filter(Predicate predicate)返回由与此给定谓词匹配的此流的元素组成的流。 --->接收Lambda,从流中排除某些元素。
//1:创建Stream; Stream stream = list.stream(); //2:filter方法(找到年龄大于等于18岁的学生) Stream studentStream = stream.filter((student) -> student.getAge() >= 18); //3:终止操作;如果没有终止操作的话,上面的第二步中间操作不执行 studentStream.forEach(System.out::println); /** * 注意:如果值执行1,2操作的话,不会有任何结果。 * 验证出Steam操作是延迟的,只有进行了终止操作,才会执行中间操作!这就是所谓的延迟加载 */
②Stream limit(Long maxSize) 返回由该流的元素组成的流,截断长度不能超过maxSize. 只有找到maxSize个满足条件的即可。 ---->截断流,使其元素不超过给定的数量。
public void limitTest02() { //Limit方法 短路(效率增高),只要找到了2个满足条件的,后面的迭代操作就不在执行了! list.stream().filter(x -> { System.out.println("正在过滤!!"); return x.getAge() > 18; }).limit(2).forEach(System.out::println); }
③Stream skip(Long n) 在丢掉流的第一个n元素后,返回由该流的n元素组成的流,如果此流包含少于n元素,那么将返回一个空流。 ---->跳过元素,返回一个扔掉了前n个元素的流。 如果流中的元素不足n个,则返回一个空流,与limit(n)互补。
public void skipTest03() { //skip 方法跳过前2个满足条件的 留下后面满足条件的结果!! list.stream().filter(x -> { System.out.println("正在过滤后面满足条件的结果"); return x.getAge() > 18; }).skip(2).forEach(System.out::println); }
④Stream distinct()
注意: 自定义的类在去重的过程中必须重新hashCode和equals方法,因为distinct实现的时候底层去找这两个方法。
public void distinctTest04() { //distinct 去重操作! list.stream().distinct().forEach(System.out::println); }
⑤ map映射:
如果需要将流中的元素映射到另一个流中,可以使用map方法。方法签名: Stream map(Function super T, ? extends R> mapper); 该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。 Stream流中的map方法基本使用的代码如:
@Test public void testMap() { Stream original = Stream.of("11", "22", "33"); Stream result = original.map(Integer::parseInt); result.forEach(s -> System.out.println(s + 10)); } //这段代码中,map方法的参数通过方法引用,将字符串类型转换成为了int类型(并自动装箱为Integer类对象)。
⑥ 排序 (两种方式)
(1)Stream sorted()返回此流元素组成的流,根据自然顺序排序。底层按照内部比较器进行排序,实现Comparable接口中的compareto方法。
(2)Stream sorted(Comparatorcomparator) 返回由此元素组成的流,根据挺的Comparator进行顺序排序。指定顺序。 指定排序策略:底层按照外部比较器进行排序 Comparator接口一定要重新Compare方法。
基本使用 Stream流中的sorted方法基本使用的代码如: @Test public void testSorted() { // sorted(): 根据元素的自然顺序排序 // sorted(Comparator super T> comparator): 根据比较器指定的规则排序 Stream.of(33, 22, 11, 55) .sorted() .sorted((o1, o2) -> o2 - o1) .forEach(System.out::println); } 这段代码中,sorted方法根据元素的自然顺序排序,也可以指定比较器排序。
4:终止操作
①查找(find)和匹配(match)
Optional findFirst();
Optional findAny();
@Test public void testFind() { Optional first = Stream.of(5, 3, 6, 1).findFirst(); System.out.println("first = " + first.get()); Optional any = Stream.of(5, 3, 6, 1).findAny(); System.out.println("any = " + any.get()); }
Stream流的match方法
如果需要判断数据是否匹配指定的条件,可以使用Match相关方法。方法签名:
boolean allMatch(Predicate super T> predicate);
boolean anyMatch(Predicate super T> predicate);
boolean noneMatch(Predicate super T> predicate);
@Test public void testmatch() { boolean b = Stream.of(5, 3, 6, 1) // .allMatch(e -> e > 0); // allMatch: 元素是否全部满足条件 // .anyMatch(e -> e > 5); // anyMatch: 元素是否任意有一个满足条件 .noneMatch(e -> e
②:遍历 foreach
//forEach 用来遍历流中的数据 @Test public void test02() { //案例1、2下面两种写法等同 list.stream().map((x)->x.getName()).forEach(System.out::println); list.stream().map(Student::getName).forEach(System.out::println); }
③Stream流的max、min
List list13 = Arrays.asList("zhangsan","lisi","wangwu","xuwujing"); int maxLines = list13.stream().mapToInt(String::length).max().getAsInt(); int minLines = list13.stream().mapToInt(String::length).min().getAsInt(); System.out.println("最长字符的长度:" + maxLines+",最短字符的长度:"+minLines); //最长字符的长度:8,最短字符的长度:4
④Stream流的count
// Stream流提供count方法来统计其中的元素个数:long count(); //该方法返回一个long值代表元素个数。基本使用: @Test public void testCount() { List strList = new ArrayList(); Collections.addAll(strList, "张无忌", "周芷若", "赵敏", "小昭", "杨不悔); System.out.println(strList.stream().count()); }
⑤ 分组:groupingBy;
当我们使用Stream流处理数据后,可以根据某个属性将数据分组:
// 案例: @Test public void testGroup() { Stream studentStream = Stream.of( new Student("赵丽颖", 52, 95), new Student("杨颖", 56, 88), new Student("迪丽热巴", 56, 55), new Student("柳岩", 52, 33)); // Map> map = studentStream.collect(Collectors.groupingBy(Student::getAge)); // 将分数大于60的分为一组,小于60分成另一组 Map> map = studentStream.collect(Collectors.groupingBy((s) -> { if (s.getSocre() > 60) { return "及格"; } else { return "不及格"; } })); map.forEach((k, v) -> { System.out.println(k + "::" + v); }); }
效果: 不及格::[Student{name='迪丽热巴', age=56, socre=55}, Student{name='柳岩', age=52, socre=33}] 及格::[Student{name='赵丽颖', age=52, socre=95}, Student{name='杨颖', age=56, socre=88}]
⑥拼接:joining
Collectors.joining会根据指定的连接符,将所有元素连接成一个字符串。 // 拼接 @Test public void testJoining() { Stream studentStream = Stream.of( new Student("赵丽颖", 52, 95), new Student("杨颖", 56, 88), new Student("迪丽热巴", 56, 99), new Student("柳岩", 52, 77)); String collect = studentStream .map(Student::getName) .collect(Collectors.joining(">_
效果:
^_^赵丽颖>___
⑦聚合:toList,toSet,toMap;
Stream流提供collect方法,其参数需要一个java.util.stream.Collector接口对象来指定收集到哪种集合中。
public static Collector toList():转换为List集合。
public static Collector toSet():转换为Set集合。
public static Collector> toMap(Function super T, ? extends K> keyMapper, Function super T, ? extends U> valueMapper):转换为Map集合。
// 将流中数据收集到集合中 @Test public void testStreamToCollection() { Stream stream = Stream.of("aa", "bb", "cc"); // List strList = stream.collect(Collectors.toList()); // Set strSet = stream.collect(Collectors.toSet()); ArrayList arrayList = stream.collect(Collectors.toCollection(ArrayList::new)); HashSet hashSet = stream.collect(Collectors.toCollection(HashSet::new)); }
toMap
@Test public void testCollectToMap(){ //案例1 List list = Arrays.asList(1, 2, 3); Map collect1 = list.stream().map(i -> i).collect(Collectors.toMap(key -> "key" + key, value -> "value:" + value)); //实体list转化map id作为主键,对象作为value List userList =new ArrayList(); UserTask userTask = new UserTask(); userTask.setId(1); userTask.setName("测试"); userList.add(userTask); Map taskMap = userList.stream().collect(Collectors.toMap(UserTask::getId, entity -> entity)); System.out.println(collect1.toString()); System.out.println(taskMap.toString()); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。