本篇内容介绍了“JAVA8中Stream的特性和使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
一、Stream的使用
1.1 创建
1.2 步骤
二、Stream的特性
三、中间操作
3.1 filter()
3.2 limit()
3.3 skip()
3.4 map()
3.5 sorted
四、终止操作
4.1 allMatch
4.2anyMatch
4.3noneMatch
4.4 findFirst()
4.5 findAny()
4.6 count
4.7 max
4.8 min
4.9 forEach
4.10 reduce
4.11 collect
通过Collection接口的实现类提供的 stream()方法,或
通过Arrays中的静态方法 stream()获取
通过Stream类中的静态方法 of()
无限流(迭代/生成)
/** * @Author: 郜宇博 * @Date: 2021/9/1 23:28 * 流操作 */ public class StreamTests { @Test public void test(){ //1.通过Collection接口的实现类提供的 stream()方法,或 Collection<String> list = new ArrayList<>(); list.stream(); list.parallelStream(); //2.通过Arrays中的静态方法 stream()获取 Integer[] integers = new Integer[10]; Arrays.stream(integers); //3.通过Stream类中的静态方法 of() Stream<String> stream = Stream.of("1","2"); //4.无限流 //迭代 Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2); //生成 Stream<Double> generate = Stream.generate(() -> Math.random()); } }
parallelStream提供了流的并行处理,它是Stream的另一重要特性,其底层使用Fork/Join框架实现。简单理解就是多线程异步任务的一种实现。
创建Stream;
转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换);
对Stream进行聚合(Reduce)操作,获取想要的结果;
惰性求值:
多个中间操作
可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何处理!而是在终止操作时一次性全部处理,这种情况称为“惰性求值”。
筛选与切片
接受lambda表达式,从流中排除某些元素
@Test public void test2(){ //获取一个数组 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:获取大于5的 arrayList.stream().filter((num)->num>5).forEach(System.out::println); } //结果: 6 7 8 9
截断流,使其元素个数不超过一定数量
满足limit的数量后,就短路,不在执行后续操作
@Test public void test2(){ //获取一个数组 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:获取大于5的 arrayList.stream().filter((num)->num>5) .limit(2) .forEach(System.out::println); } //结果: 6 7
跳过元素,跳过前n个元素,执行后面的元素,如果不足n个则返回空流
@Test public void test2(){ //获取一个数组 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:获取大于5的 arrayList.stream().filter((num)->num>5) .skip(2) .forEach(System.out::println); } //结果: 8 9 3.3 map() 映射,在方法中使用方法Function< T> 函数型接口 -----> R apply(T t); @Test public void test4(){ //获取一个list List<String> list = Arrays.asList("aaa","bbb","ccc"); //使用流操作 转化大写 list.stream().map((str)->str.toUpperCase()) .forEach(System.out::println); } /*结果:AAA BBB CCC*/ @Test public void test3(){ //获取一个list List<String> list = Arrays.asList("aaa","bbb","ccc"); //流操作: 将list中的元素取出 //第一步使用map取出流,流里存放的还是流 //因此需要二次foreach Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper); chs.forEach((stream)->{ stream.forEach(System.out::print); }); } //将str返回为流对象 public static Stream<Character> getUpper(String str){ List<Character> list = new ArrayList<>(); for (Character character: str.toCharArray()){ list.add(character); } return list.stream(); } //结果:aaabbbccc
映射,在方法中使用方法Function< T> 函数型接口 -----> R apply(T t);
@Test public void test4(){ //获取一个list List<String> list = Arrays.asList("aaa","bbb","ccc"); //使用流操作 转化大写 list.stream().map((str)->str.toUpperCase()) .forEach(System.out::println); } /*结果:AAA BBB CCC*/
@Test public void test3(){ //获取一个list List<String> list = Arrays.asList("aaa","bbb","ccc"); //流操作: 将list中的元素取出 //第一步使用map取出流,流里存放的还是流 //因此需要二次foreach Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper); chs.forEach((stream)->{ stream.forEach(System.out::print); }); } //将str返回为流对象 public static Stream<Character> getUpper(String str){ List<Character> list = new ArrayList<>(); for (Character character: str.toCharArray()){ list.add(character); } return list.stream(); } //结果:aaabbbccc
相当于集合方法的 addAll
即:将流中的流内元素取出,放入一个流中,而不是流内套流
@Test public void test3(){ //获取一个list List<String> list = Arrays.asList("aaa","bbb","ccc"); //流操作: 将list中的元素取出 //第一步使用map取出流,流里存放的还是流 //因此需要二次foreach Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper); chs.forEach((stream)-> stream.forEach(System.out::print)); System.out.println("\n====="); //方法二: //使用flatMap list.stream().flatMap(StreamTests::getUpper).forEach(System.out::print); }
@Test public void test5(){ List<String> list = Arrays.asList("aaa", "ccc", "bbbb", "eeeee"); //自然排序 list.stream() .sorted() .forEach(System.out::println); System.out.println("============="); //定制排序 list.stream() .sorted((x,y)->{ //如果长度一样,则按照字典排序 if (x.length() == y.length()){ return x.compareTo(y); } //如果长度不一样则按照长度的降序排序 else { return y.length() - x.length(); } }) .forEach(System.out::println); } /*结果: aaa bbbb ccc eeeee ============= eeeee bbbb aaa ccc */
查找与匹配
Predicate<? super T> predicate /** * @Author: 郜宇博 * @Date: 2021/9/3 14:00 * 终止操作 */ public class FinalOperation { static ArrayList<Student> list; /** * allMath 检查是否全部元素符合 */ @BeforeEach public void before(){ //准备集合 Student student1 = new Student(10,"张三", Student.Status.Sad); Student student2 = new Student(20,"李四", Student.Status.Happy); Student student3 = new Student(30,"王五", Student.Status.Free); Student student4 = new Student(18,"田七", Student.Status.Free); Student student5 = new Student(140,"赵六", Student.Status.Tired); list = new ArrayList<>(); list.add(student1); list.add(student2); list.add(student3); list.add(student4); list.add(student5); } } class Student{ private int age; private String name; private Status status; public int getAge() { return age; } public String getName() { return name; } public Status getStatus() { return status; } /** * 枚举状态 */ public enum Status{ Free,Tired,Happy,Sad; } public Student(int age, String name, Status status) { this.age = age; this.name = name; this.status = status; } } /** * 是否全部年龄都大于20 */ @Test public void test1(){ boolean b = list.stream().allMatch((s) -> s.getAge() > 20); System.out.println(b); } //结果: false
Predicate<? super T> predicate /** * 是否存在年龄大于20的 */ @Test public void test2(){ boolean b = list.stream().anyMatch((s) -> s.getAge() > 20); System.out.println(b); } //结果:true
Predicate<? super T> predicate /** * 是否没有满足年龄大于20的 * */ @Test public void test3(){ boolean b = list.stream().noneMatch((s) -> s.getAge() > 20); System.out.println(b); } //结果:false
返回第一元素,但结果可能为null, 因此使用Optional<T> 来接收,如果为null则可以替换。
/** * 返回第一元素 */ @Test public void test4(){ Optional<Student> first = list.stream() .filter((e) -> e.getStatus().equals(Student.Status.Free)) .findFirst(); System.out.println(first); } //结果:Optional[Student{age=30, name='王五', status=Free}]
返回任意一个
/** * 返回任意一个 * */ @Test public void test5(){ Optional<Student> b = list.parallelStream() .filter((student -> student.getAge()<30)) .findAny(); System.out.println(b.get()); } //结果: 任意一个年龄小于30的学生
/** * 获取数量count */ @Test public void test6(){ long count = list.stream().count(); System.out.println(count); } //结果 : 5
/** * 获得最大值 */ @Test public void test7(){ Optional<Integer> max = list.stream() .map(x->x.getAge()) .max(Integer::compare); System.out.println(max.get()); } //结果: 140
/** * 获得最小值 */ @Test public void test7(){ Optional<Integer> max = list.stream() .map(x->x.getAge()) .min(Integer::compare); System.out.println(max.get()); }
@Test public void test2(){ //获取一个数组 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:获取大于5的 arrayList.stream().filter((num)->num>5) .limit(2) .forEach(System.out::println); } //结果: 6 7
/** * 归纳 */ @Test public void test8(){ Integer reduce = list.stream() .map(Student::getAge) .reduce(0, (x, y) -> x + y); System.out.println(reduce); //方法二: //此方法有可能为null,因此封装为Optional对象 Optional<Integer> reduce1 = list.stream() .map(Student::getAge) .reduce(Integer::sum); System.out.println(reduce1.get()); }
可以收集为集合类,
可以在收集后进行分组、多级分组、分片
/** * 收集 */ @Test public void test9(){ List<Student> collect = list.stream().collect(Collectors.toList()); collect.forEach(System.out::println); //方式二: HashSet<Student> collect1 = list.stream().collect(Collectors.toCollection(HashSet::new)); collect.forEach(System.out::println); } /* 结果:Student{age=10, name='张三', status=Sad} Student{age=20, name='李四', status=Happy} Student{age=30, name='王五', status=Free} Student{age=18, name='田七', status=Free} Student{age=140, name='赵六', status=Tired} */ /** * 使用收集可以计算最大值、最小值、平均值、等 * 也可以进行分组 */ @Test public void test10(){ Map<Student.Status, List<Student>> collect = list.stream().collect(Collectors.groupingBy((x) -> x.getStatus())); System.out.println(collect.size()); System.out.println(collect); }
“JAVA8中Stream的特性和使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。