Java8에서 스트림을 사용하는 방법
1. 베테랑들이 Stream을 선호하는 이유
성능 장점, (대량 데이터 용량) Iterator에 비해 속도가 빠릅니다
직렬 및 병렬 처리 지원, 병렬 처리더 많은 CPU 활용 가능 resources
Stream은 데이터 계산을 위한 스트림이며 데이터 자체를 저장하지 않습니다
함수형 프로그래밍을 지원합니다
코드가 우아하여 코드를 더욱 효율적이고 깨끗하며 간결하게 만듭니다
2. Stream 사용 방법
3단계:
Stream
생성Stream
中间操作
终止操作
3. Stream 的创建
Stream
的 创建都会依赖于数据源,通常是容器或者数组 Stream
流的创建大致分为4中,最为常用的就是通过集合创建
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream; public class CreateStreamDemo { public static void main(String[] args) { // 1 通过集合创建Stream也是用的最多的一种形式 List<String> strList = new ArrayList<>(); strList.add("a"); strList.add("b"); strList.add("c"); // 创建串行操作流 Stream<String> stream = strList.stream(); // 创建并行操作流 Stream<String> parallelStream = strList.parallelStream(); // 2 通过数组创建Stream int[] arr = new int[]{1,2,3}; IntStream intStream = Arrays.stream(arr); // 3 通过Stream.of Stream<Integer> integerStream = Stream.of(1,2,3); Stream<String> stringStream = Stream.of("a","b","c"); // 4 无限流 // 每隔五个数取一个 Stream.iterate(0, t -> t + 5).forEach(System.out::println); // 迭代 Stream.generate(Math::random).forEach(System.out::println); // 生成 } }
4. Stream 中间操作
Stream
中间操作,我们最为常用的就是过滤,去重,排序 本章包含我们开发最常用的对对象的去重,和更据对象中的对个属性组合排序
import com.zhj.java8.bean.Student; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.TreeSet; import java.util.stream.Stream; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toCollection; public class MiddleStreamDemo { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(1,"小华",23,1)); students.add(new Student(1,"小华",23,2)); students.add(new Student(2,"小米",20,2)); students.add(new Student(3,"小果",30,3)); students.add(new Student(4,"小维",18,2)); // 过滤 students.stream().filter(stu -> stu.getAge() > 20).forEach(System.out::println); // 去重 // 对对象去重是根据引用去重,内容重复并不会去重,除非重写equals和hashCode方法 System.out.println("----------去重----------"); System.out.println("去重1----------"); students.stream().distinct().forEach(System.out::println); // 对集合中对象某些属性去重,不重写equals和hashCode方法,只能借助其他数据结构来辅助去重 // 单个属性可以stu -> stu.getId() // 多个属性可以stu -> stu.getId() + ";" + stu.getName() System.out.println("去重2----------"); ArrayList<Student> distinctList = students.stream().collect( collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(stu -> stu.getId() + ";" + stu.getName()))), ArrayList::new) ); distinctList.stream().forEach(System.out::println); // 排序 支持定义排序方式 // sorted 默认使用 自然序排序, 其中的元素必须实现Comparable 接口 System.out.println("----------排序----------"); System.out.println("排序1----------"); students.stream().sorted().forEach(System.out::println); // sorted(Comparator<? super T> comparator) :我们可以使用lambada 来创建一个Comparator 实例。可以按照升序或着降序来排序元素。 System.out.println("排序2----------"); students.stream() .sorted(Comparator.comparing(Student::getAge,Comparator.reverseOrder())) // ,Comparator.reverseOrder() 逆序 .forEach(System.out::println); // 创建比较器,通过对比较器内容的定义实现对多个属性进行排序,类似sql中连续的orderBy System.out.println("排序3----------"); students.stream().sorted( (s1,s2) -> { if (s1.getAge() == s2.getAge()) { return s1.getSex().compareTo(s2.getSex()); } else { return -s1.getAge().compareTo(s2.getAge()); } } ).forEach(System.out::println); System.out.println("排序4----------"); Comparator<Student> studentComparator = (s1,s2) -> { Integer age1 = s1.getAge(); Integer age2 = s2.getAge(); if (age1 != age2) return age1 - age2; Integer sex1 = s1.getSex(); Integer sex2 = s2.getSex(); if (sex1 != sex2) return sex2 - sex1; return 0; }; students.stream().sorted(studentComparator).forEach(System.out::println); // 截取 截取前三个元素 System.out.println("----------截取----------"); students.stream().limit(3).forEach(System.out::println); // 跳过 跳过前3个元素 System.out.println("----------跳过----------"); students.stream().skip(3).forEach(System.out::println); // 映射 System.out.println("----------映射----------"); System.out.println("映射Map----------"); // map接收Lambda,将元素转换其他形式,或者是提取信息,并将其映射成一个新的元素 Stream<Stream<Student>> streamStream1 = students.stream().map(str -> filterStudent(str)); streamStream1.forEach(sm -> sm.forEach(System.out::println)); System.out.println("映射flatMap----------"); // map接收Lambda,将流中的每一个元素转换成另一个流,然后把所有流连成一个流 扁平化映射 Stream<Student> studentStream2 = students.stream().flatMap(str -> filterStudent(str)); studentStream2.forEach(System.out::println); // 消费 System.out.println("----------消费----------"); students.stream().peek(stu -> stu.setAge(100)).forEach(System.out::println); } public static Stream<Student> filterStudent(Student student) { student = new Student(); return Stream.of(student); } }
Student
public class Student implements Comparable<Student> { private Integer id; private String name; private Integer age; private Integer sex; public Student() { } public Student(Integer id, String name, Integer age, Integer sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } @Override public String toString() { return "Student{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age='" + age + '\'' + ", sex=" + sex + '}'; } @Override public int compareTo(Student o) { return this.getAge() - o.getAge(); } }
5. Stream 终止操作
Stream
的终止操作,最常用的就是讲处理过的数据收集到新的容器中,同时可以实现向Sql聚合函数,分组的一些效果
package com.zhj.java8.stream; import com.zhj.java8.bean.Student; import java.util.*; import java.util.stream.Collectors; public class TerminationStreamDemo { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(1,"小华",23,1)); students.add(new Student(2,"小米",20,2)); students.add(new Student(3,"小果",30,3)); students.add(new Student(4,"小维",18,2)); students.add(new Student(5,"小华",23,2)); System.out.println("--------------------匹配聚合操作--------------------"); // allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false boolean allMatch = students.stream().allMatch(stu -> stu.getAge() > 10); System.out.println("全部符合大于10岁条件:" + allMatch); // noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false boolean noneMatch = students.stream().noneMatch(stu -> stu.getAge() > 10); System.out.println("全部不符合大于10岁条件:" + noneMatch); // anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false boolean anyMatch = students.stream().anyMatch(stu -> stu.getAge() > 20); System.out.println("含有任意符合大于20岁条件:" + anyMatch); // findFirst:返回流中第一个元素 Student findFirst = students.stream().findFirst().get(); System.out.println("第一个学生:" + findFirst); // findAny:返回流中的任意元素 Student findAny = students.stream().findAny().get(); System.out.println("任意一个学生:" + findAny); // count:返回流中元素的总个数 long count = students.stream().count(); System.out.println("学生总数:" + count); // max:返回流中元素最大值 Student max = students.stream().max(Student::compareTo).get(); System.out.println("年龄最大学生:" + max); // max:返回流中元素最大值 Student min = students.stream().min(Student::compareTo).get(); System.out.println("年龄最小学生:" + min); System.out.println("--------------------规约操作--------------------"); System.out.println("学生年龄总和:" + students.stream().map(Student::getAge).reduce(Integer::sum)); System.out.println("学生年龄最大:" + students.stream().map(Student::getAge).reduce(Integer::max)); System.out.println("--------------------收集操作--------------------"); List<Student> list = students.stream().collect(Collectors.toList()); Set<Student> set = students.stream().collect(Collectors.toSet()); Map<Integer, String> map = students.stream().collect(Collectors.toMap(Student::getId, Student::getName)); String joinName = students.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")")); // 总数 students.stream().collect(Collectors.counting()); // 最大年龄 students.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get(); // 年龄和 students.stream().collect(Collectors.summingInt(Student::getAge)); // 平均年龄 students.stream().collect(Collectors.averagingDouble(Student::getAge)); // 信息合集 DoubleSummaryStatistics statistics = students.stream().collect(Collectors.summarizingDouble(Student::getAge)); System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage()); // 分组 Map<Integer, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getSex)); System.out.println(collect); //多重分组,先根据性别分再根据年龄分 Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge))); //分区 //分成两部分,一部分大于20岁,一部分小于等于20岁 Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 20)); //规约 Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get(); System.out.println(allAge); } }
6. Stream 特性
中间操作惰性执行
多个中间操作的话,不会多次循环,多个转换操作只会在终止操作的时候融合起来,一次循环完成。
内部迭代
找到符合条件的数据后边的迭代不会进行
流的末端操作只有一次
异常:stream has already been operated upon or closed
중간 작업
🎜🎜종료 작업🎜🎜🎜🎜3.Stream
은 데이터 소스(일반적으로 컨테이너 또는 배열)에 따라 다릅니다. Stream
스트림 생성은 대략 4가지 유형으로 구분됩니다. 가장 일반적으로 사용되는 유형은 스트림을 생성하는 것입니다. 컬렉션을 통해🎜rrreee🎜 4. 스트림 중간 작업🎜🎜스트림
중간 작업으로 가장 일반적으로 사용되는 작업은 필터링, 중복 제거 및 정렬입니다. 이 장에는 가장 일반적으로 사용되는 객체 중복 제거 및 업데이트가 포함되어 있습니다. 속성 조합 정렬🎜rrreee🎜🎜Student🎜🎜rrreee🎜5. 스트림 종료 작업🎜🎜Stream
의 종료 작업으로, 가장 일반적으로 사용되는 작업은 처리된 데이터를 새 컨테이너에 수집하는 것입니다. , 동시에 구현 가능 SQL 집계 함수에 대한 그룹화의 일부 효과 🎜rrreee🎜6. 스트림 기능 🎜🎜🎜중간 작업이 느리게 실행됨 🎜🎜🎜중간 작업이 여러 번 있는 경우 여러 번 반복되지 않습니다. 🎜여러 변환 작업은 작업이 종료되고 함께 융합되어 하나의 사이클이 완료되는 경우에만 실행됩니다🎜. 🎜🎜🎜🎜내부 반복🎜🎜🎜🎜기준에 맞는 데이터를 찾은 후 이어지는 반복은 수행되지 않습니다.🎜🎜🎜🎜스트림의 종료 작업은 한 번만 수행됩니다.🎜🎜🎜🎜🎜예외: 🎜스트림에 이미 작동했거나 닫혔습니다
🎜🎜는 스트림이 닫혔음을 의미합니다. 왜냐하면 end 작업을 사용하면 🎜스트림이 닫혀서 다시 호출할 수 없기 때문입니다🎜. 새로운 흐름만 다시 열 수 있습니다. 🎜위 내용은 Java8에서 스트림을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Java의 난수 생성기 안내. 여기서는 예제를 통해 Java의 함수와 예제를 통해 두 가지 다른 생성기에 대해 설명합니다.

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4
