Dieser Artikel vermittelt Ihnen relevantes Wissen über Java und stellt hauptsächlich verwandte Probleme zur detaillierten Verwendung von Stream vor. Der neue Stream in der Version bietet uns zusammen mit dem Lambda, das in derselben Version erscheint, eine großartige Möglichkeit, Sammlungen zu betreiben ( Sammlung). Tolle Bequemlichkeit, schauen wir uns das unten an, ich hoffe, es wird für alle hilfreich sein.
Empfohlenes Lernen: „Java-Video-Tutorial“
Java 8 ist eine sehr erfolgreiche Version, kombiniert mit dem Lambda, das in derselben Version erscheint Eine Reihe von Operationen (Collection) bietet großen Komfort. Stream ist ein neues Mitglied von JDK8, das die deklarative Verarbeitung von Datensammlungen ermöglicht. Der Stream-Stream kann als erweiterter Iterator zum Durchlaufen der Datensammlung betrachtet werden. Stream ist das zentrale abstrakte Konzept für die Verarbeitung von Sammlungen in Java 8. Es kann die Vorgänge angeben, die Sie für die Sammlung ausführen möchten, und kann sehr komplexe Vorgänge wie das Suchen/Filtern/Filtern, Sortieren, Aggregieren und Zuordnen von Daten ausführen. Die Verwendung der Stream-API zum Bearbeiten von Sammlungsdaten ähnelt der Verwendung von SQL zum Durchführen von Datenbankabfragen. Sie können die Stream-API auch verwenden, um Vorgänge parallel auszuführen. Kurz gesagt, die Stream-API bietet eine effiziente und benutzerfreundliche Möglichkeit, Daten zu verarbeiten.
Code ist deklarativ geschrieben und beschreibt, was er erreichen möchte, und nicht, wie eine Operation ausgeführt werden soll.
Mehrere Grundoperationen können verbunden werden, um komplexe Datenverarbeitungspipelines auszudrücken und gleichzeitig den Code klar und lesbar zu halten.
Erzeugt eine Folge von Elementen aus einer Quelle, die Datenverarbeitungsvorgänge unterstützt. Die Datenquelle kann eine Sammlung, ein Array oder eine E/A-Ressource sein.
Aus betrieblicher Sicht unterscheiden sich Streams von Sammlungen. Der Zweck von Streams besteht nicht darin, Daten zu verarbeiten, sondern in Algorithmen und Berechnungen.
Wenn Sie eine Sammlung als Datenquelle eines Streams verwenden, führt die Erstellung des Streams nicht zum Datenfluss. Wenn für die Beendigungsoperation des Streams ein Wert erforderlich ist, erhält der Stream nur den Wert aus der Sammlung einmal verwendet.
Die zentrale Idee von Streams besteht darin, die Berechnung zu verzögern, und Streams berechnen Werte erst, wenn sie benötigt werden.
Streams können aus einem Array oder einer Sammlung erstellt werden. Operationen an Streams werden in zwei Typen unterteilt:
Zwischenoperationen: Jedes Mal, wenn ein neuer Stream zurückgegeben wird, kann es mehrere geben.
Terminaloperation: Jeder Stream kann nur eine Terminaloperation ausführen und der Stream kann nach Abschluss der Terminaloperation nicht erneut verwendet werden. Terminaloperationen erzeugen eine neue Sammlung oder einen neuen Wert.
Eigenschaften:
ist keine Datenstruktur und speichert keine Daten.
Die ursprüngliche Datenquelle wird nicht geändert, sondern die verarbeiteten Daten werden in einem anderen Objekt gespeichert. (Vorbehalt: Schließlich kann die Peek-Methode die Elemente im Stream ändern)
Während der Zwischenverarbeitung des Streams wird der Vorgang nur aufgezeichnet und nicht sofort ausgeführt wird vor der eigentlichen Berechnung durchgeführt.
Stateless: bedeutet, dass die Verarbeitung von Elementen nicht durch vorherige Elemente beeinflusst wird;
Stateful: bedeutet, dass der Vorgang erst fortgesetzt werden kann, nachdem alle Elemente abgerufen wurden.
Nicht-Kurzschlussbetrieb: bedeutet, dass alle Elemente verarbeitet werden müssen, um das Endergebnis zu erhalten.
Kurzschlussbetrieb: bedeutet, dass das Endergebnis erzielt werden kann, wenn bestimmte Elemente angetroffen werden, die die Bedingungen erfüllen, z. B. A ||. B. Solange A wahr ist, ist kein Urteil erforderlich. Das Ergebnis von B.
Stream kann über ein Sammlungsarray erstellt werden.
1. Verwenden Sie die Methode java.util.Collection.stream(), um einen Stream mit einer Sammlung zu erstellen
List<string> list = Arrays.asList("a", "b", "c");// 创建一个顺序流 Stream<string> stream = list.stream();// 创建一个并行流 Stream<string> parallelStream = list.parallelStream();</string></string></string>
2. Verwenden Sie die Methode java.util.Arrays.stream(T[]array), um einen Stream mit einem zu erstellen Array
int[] array={1,3,5,6,8};IntStream stream = Arrays.stream(array);
3. Verwenden Sie die statischen Methoden „of()“, „iterate()“, „generate()“
Stream<integer> stream = Stream.of(1, 2, 3, 4, 5, 6); Stream<integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);stream2.forEach(System.out::println); Stream<double> stream3 = Stream.generate(Math::random).limit(3);stream3.forEach(System.out::println);</double></integer></integer>
Ausgabeergebnisse:
0 3 6 90.67961569092719940.19143142088542830.8116932592396652
Eine einfache Unterscheidung zwischen Stream und ParallelStream: Stream ist ein sequentieller Stream und der Hauptthread Führt Vorgänge für den Stream nacheinander aus, während parallelStream ein paralleler Stream ist. Er betreibt den Stream intern in einer parallelen Multithread-Ausführungsweise, aber die Voraussetzung ist, dass für die Datenverarbeitung im Stream keine Reihenfolge erforderlich ist. Wenn Sie beispielsweise ungerade Zahlen in einer Sammlung filtern, ist der Verarbeitungsunterschied zwischen den beiden wie folgt:
Wenn die Datenmenge im Stream groß genug ist, können parallele Streams die Verarbeitung beschleunigen.
Zusätzlich zum direkten Erstellen paralleler Streams können Sie sequentielle Streams auch über parallel() in parallele Streams konvertieren:
Optional<integer> findFirst = list.stream().parallel().filter(x->x>6).findFirst();</integer>
先贴上几个案例,水平高超的同学可以挑战一下:从员工集合中筛选出salary大于8000的员工,并放置到新的集合里。统计员工的最高薪资、平均薪资、薪资之和。将员工按薪资从高到低排序,同样薪资者年龄小者在前。将员工按性别分类,将员工按性别和地区分类,将员工按薪资是否高于8000分为两部分。用传统的迭代处理也不是很难,但代码就显得冗余了,跟Stream相比高下立判。
Voraussetzung: Mitarbeiterklasse
static List<person> personList = new ArrayList<person>();private static void initPerson() { personList.add(new Person("张三", 8, 3000)); personList.add(new Person("李四", 18, 5000)); personList.add(new Person("王五", 28, 7000)); personList.add(new Person("孙六", 38, 9000));}</person></person>
Stream unterstützt auch sammlungsähnliche Traversal- und Matching-Elemente, außer dass die Elemente im Stream als optionale Typen existieren. Stream-Durchquerung und Matching sind sehr einfach.
// import已省略,请自行添加,后面代码亦是 public class StreamTest { public static void main(String[] args) { List<integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1); // 遍历输出符合条件的元素 list.stream().filter(x -> x > 6).forEach(System.out::println); // 匹配第一个 Optional<integer> findFirst = list.stream().filter(x -> x > 6).findFirst(); // 匹配任意(适用于并行流) Optional<integer> findAny = list.parallelStream().filter(x -> x > 6).findAny(); // 是否包含符合特定条件的元素 boolean anyMatch = list.stream().anyMatch(x -> x <h3>2、按条件匹配filter</h3> <p><img src="https://img.php.cn/upload/article/000/000/067/c32799257ddfee7ae65dfaf7bce4b27c-5.png" alt="在这里插入Zusammenfassung der detaillierten Verwendung von Stream in Java8描述"></p> <p><strong>(1)筛选员工中已满18周岁的人,并形成新的集合</strong></p> <pre class="brush:php;toolbar:false">/** * 筛选员工中已满18周岁的人,并形成新的集合 * @思路 * List<person> list = new ArrayList<person>(); * for(Person person : personList) { * if(person.getAge() >= 18) { * list.add(person); * } * } */ private static void filter01() { initPerson(); List<person> collect = personList.stream().filter(x -> x.getAge()>=18).collect(Collectors.toList()); System.out.println(collect);}</person></person></person>
(2)自定义条件匹配
(1)获取String集合中最长的元素
/** * 获取String集合中最长的元素 * @思路 * List<string> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu"); * String max = ""; * int length = 0; * int tempLength = 0; * for(String str : list) { * tempLength = str.length(); * if(tempLength > length) { * length = str.length(); * max = str; * } * } * @return zhangsan */ private static void test02() { List<string> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu"); Comparator super String> comparator = Comparator.comparing(String::length); Optional<string> max = list.stream().max(comparator); System.out.println(max);}</string></string></string>
(2)获取Integer集合中的最大值
//获取Integer集合中的最大值 private static void test05() { List<integer> list = Arrays.asList(1, 17, 27, 7); Optional<integer> max = list.stream().max(Integer::compareTo); // 自定义排序 Optional<integer> max2 = list.stream().max(new Comparator<integer>() { @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }); System.out.println(max2);}</integer></integer></integer></integer>
//获取员工中年龄最大的人 private static void test06() { initPerson(); Comparator super Person> comparator = Comparator.comparingInt(Person::getAge); Optional<person> max = personList.stream().max(comparator); System.out.println(max);}</person>
(3)获取员工中年龄最大的人
(4)计算integer集合中大于10的元素的个数
map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
(1)字符串大写
(2)整数数组每个元素+3
/** * 整数数组每个元素+3 * @思路 * List<integer> list = Arrays.asList(1, 17, 27, 7); List<integer> list2 = new ArrayList<integer>(); for(Integer num : list) { list2.add(num + 3); } @return [4, 20, 30, 10] */ private static void test09() { List<integer> list = Arrays.asList(1, 17, 27, 7); List<integer> collect = list.stream().map(x -> x + 3).collect(Collectors.toList()); System.out.println(collect);}</integer></integer></integer></integer></integer>
(3)公司效益好,每人涨2000
/** * 公司效益好,每人涨2000 * */ private static void test10() { initPerson(); List<person> collect = personList.stream().map(x -> { x.setAge(x.getSalary()+2000); return x; }).collect(Collectors.toList()); System.out.println(collect);}</person>
(4)将两个字符数组合并成一个新的字符数组
/** * 将两个字符数组合并成一个新的字符数组 * */ private static void test11() { String[] arr = {"z, h, a, n, g", "s, a, n"}; List<string> list = Arrays.asList(arr); System.out.println(list); List<string> collect = list.stream().flatMap(x -> { String[] array = x.split(","); Stream<string> stream = Arrays.stream(array); return stream; }).collect(Collectors.toList()); System.out.println(collect);}</string></string></string>
(5)将两个字符数组合并成一个新的字符数组
/** * 将两个字符数组合并成一个新的字符数组 * @return [z, h, a, n, g, s, a, n] */ private static void test11() { String[] arr = {"z, h, a, n, g", "s, a, n"}; List<string> list = Arrays.asList(arr); List<string> collect = list.stream().flatMap(x -> { String[] array = x.split(","); Stream<string> stream = Arrays.stream(array); return stream; }).collect(Collectors.toList()); System.out.println(collect);}</string></string></string>
归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。
(1)求Integer集合的元素之和、乘积和最大值
/** * 求Integer集合的元素之和、乘积和最大值 * */ private static void test13() { List<integer> list = Arrays.asList(1, 2, 3, 4); //求和 Optional<integer> reduce = list.stream().reduce((x,y) -> x+ y); System.out.println("求和:"+reduce); //求积 Optional<integer> reduce2 = list.stream().reduce((x,y) -> x * y); System.out.println("求积:"+reduce2); //求最大值 Optional<integer> reduce3 = list.stream().reduce((x,y) -> x>y?x:y); System.out.println("求最大值:"+reduce3);}</integer></integer></integer></integer>
(2)求所有员工的工资之和和最高工资
/* * 求所有员工的工资之和和最高工资 */ private static void test14() { initPerson(); Optional<integer> reduce = personList.stream().map(Person :: getSalary).reduce(Integer::sum); Optional<integer> reduce2 = personList.stream().map(Person :: getSalary).reduce(Integer::max); System.out.println("工资之和:"+reduce); System.out.println("最高工资:"+reduce2);}</integer></integer>
取出大于18岁的员工转为map
/** * 取出大于18岁的员工转为map * */ private static void test15() { initPerson(); Map<string> collect = personList.stream().filter(x -> x.getAge() > 18).collect(Collectors.toMap(Person::getName, y -> y)); System.out.println(collect);}</string>
Collectors提供了一系列用于数据统计的静态方法:
计数: count
平均值: averagingInt、 averagingLong、 averagingDouble
最值: maxBy、 minBy
求和: summingInt、 summingLong、 summingDouble
统计以上所有: summarizingInt、 summarizingLong、 summarizingDouble
/** * 统计员工人数、平均工资、工资总额、最高工资 */ private static void test01(){ //统计员工人数 Long count = personList.stream().collect(Collectors.counting()); //求平均工资 Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary)); //求最高工资 Optional<integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare)); //求工资之和 Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary)); //一次性统计所有信息 DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary)); System.out.println("统计员工人数:"+count); System.out.println("求平均工资:"+average); System.out.println("求最高工资:"+max); System.out.println("求工资之和:"+sum); System.out.println("一次性统计所有信息:"+collect);}</integer>
分区:将stream按条件分为两个 Map,比如员工按薪资是否高于8000分为两部分。
分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组
public class StreamTest { public static void main(String[] args) { personList.add(new Person("zhangsan",25, 3000, "male", "tieling")); personList.add(new Person("lisi",27, 5000, "male", "tieling")); personList.add(new Person("wangwu",29, 7000, "female", "tieling")); personList.add(new Person("sunliu",26, 3000, "female", "dalian")); personList.add(new Person("yinqi",27, 5000, "male", "dalian")); personList.add(new Person("guba",21, 7000, "female", "dalian")); // 将员工按薪资是否高于8000分组 Map<boolean>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000)); // 将员工按性别分组 Map<string>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex)); // 将员工先按性别分组,再按地区分组 Map<string>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea))); System.out.println("员工按薪资是否大于8000分组情况:" + part); System.out.println("员工按性别分组情况:" + group); System.out.println("员工按性别、地区:" + group2); }}</string></string></boolean>
joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
将员工按工资由高到低(工资一样则按年龄由大到小)排序
private static void test04(){ // 按工资升序排序(自然排序) List<string> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName) .collect(Collectors.toList()); // 按工资倒序排序 List<string> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()) .map(Person::getName).collect(Collectors.toList()); // 先按工资再按年龄升序排序 List<string> newList3 = personList.stream() .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName) .collect(Collectors.toList()); // 先按工资再按年龄自定义排序(降序) List<string> newList4 = personList.stream().sorted((p1, p2) -> { if (p1.getSalary() == p2.getSalary()) { return p2.getAge() - p1.getAge(); } else { return p2.getSalary() - p1.getSalary(); } }).map(Person::getName).collect(Collectors.toList()); System.out.println("按工资升序排序:" + newList); System.out.println("按工资降序排序:" + newList2); System.out.println("先按工资再按年龄升序排序:" + newList3); System.out.println("先按工资再按年龄自定义降序排序:" + newList4);}</string></string></string></string>
流也可以进行合并、去重、限制、跳过等操作。
private static void test05(){ String[] arr1 = { "a", "b", "c", "d" }; String[] arr2 = { "d", "e", "f", "g" }; Stream<string> stream1 = Stream.of(arr1); Stream<string> stream2 = Stream.of(arr2); // concat:合并两个流 distinct:去重 List<string> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList()); // limit:限制从流中获得前n个数据 List<integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList()); // skip:跳过前n个数据 List<integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList()); System.out.println("流合并:" + newList); System.out.println("limit:" + collect); System.out.println("skip:" + collect2);}</integer></integer></string></string></string>
//计算两个list中的差集 List<string> reduce1 = allList.stream().filter(item -> !wList.contains(item)).collect(Collectors.toList());</string>
推荐学习:《java视频教程》
Das obige ist der detaillierte Inhalt vonZusammenfassung der detaillierten Verwendung von Stream in Java8. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!