首頁/ 汽車/ 正文

Java8 Stream流中的 collect() 方法,遠比你想象中的強大

Stream流 collect() 方法的使用介紹

//1。 R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner);//2。 R collect(Collector<? super T, A, R> collector);

Stream 流的注意事項:Stream不呼叫終止方法,中間的操作不會執行。

但是,當我們對 Stream 流中的資料操作完成之後,如果需要將流的結果進行儲存,方便我們接下來對結果的繼續操作,該怎麼辦呢?

Stream 流提供了一個 collect() 方法,可以收集流中的資料到【集合】或者【陣列】中去。

1。收集 Stream 流中的資料到集合中

//1。收集資料到list集合中stream。collect(Collectors。toList())//2。收集資料到set集合中stream。collect(Collectors。toSet())//3。收集資料到指定的集合中Collectors。toCollection(Supplier collectionFactory)stream。collect(Collectors。joining())

示例如下:

/** * 收集Stream流中的資料到集合中 * 備註:切記Stream流只能被消費一次,流就失效了 * 如下只是示例程式碼 */public class CollectDataToCollection{ public static void main(String[] args) { //Stream 流 Stream stream = Stream。of(“aaa”, “bbb”, “ccc”, “bbb”); //收集流中的資料到集合中 //1。收集流中的資料到 list List list = stream。collect(Collectors。toList()); System。out。println(list); //2。收集流中的資料到 set Set collect = stream。collect(Collectors。toSet()); System。out。println(collect); //3。收集流中的資料(ArrayList)(不收集到list,set等集合中,而是)收集到指定的集合中 ArrayList arrayList = stream。collect(Collectors。toCollection(ArrayList::new)); System。out。println(arrayList); //4。收集流中的資料到 HashSet HashSet hashSet = stream。collect(Collectors。toCollection(HashSet::new)); System。out。println(hashSet); }}

測試結果:

[aaa, bbb, ccc, bbb][aaa, ccc, bbb][aaa, bbb, ccc, bbb][aaa, ccc, bbb]

2。收集 Stream 流中的資料到陣列中

//1。使用無參,收集到陣列,返回值為 Object[](Object型別將不好操作)Object[] toArray();//2。使用有參,可以指定將資料收集到指定型別陣列,方便後續對陣列的操作 A[] toArray(IntFunction generator);

示例如下:

/** * 收集Stream流中的資料到陣列中 * 備註:切記Stream流只能被消費一次,流就失效了 * 如下只是示例程式碼 */public class CollectDataToArray{ public static void main(String[] args) { //Stream 流 Stream stream = Stream。of(“aaa”, “bbb”, “ccc”, “bbb”); //2。1 使用 toArray()無參 Object[] objects = stream。toArray(); for (Object o: objects) {//此處無法使用。length() 等方法 System。out。println(“data:”+o); } //2。2 使用有參返回指定型別陣列 //無參不好的一點就是返回的是 Object[] 型別,操作比較麻煩。想要拿到長度,Object是拿不到長度的 String[] strings = stream。toArray(String[]::new); for(String str : strings){ System。out。println(“data:”+str + “,length:”+str。length()); } }}

測試結果:

data:aaadata:bbbdata:cccdata:bbb————————-data:aaa,length:3data:bbb,length:3data:ccc,length:3data:bbb,length:3

3。Stream流中資料聚合/分組/分割槽/拼接操作

除了 collect() 方法將資料收集到集合/陣列中。對 Stream流 的收集還有其他的方法。比如說:聚合計算,分組,多級分組,分割槽,拼接等。

附:Student實體類(接下來介紹,將根據Student類來進行聚合、分組、分割槽、拼接介紹)

/** * TODO Student實體類 * * @author liuzebiao */public class Student { private String name; private int age; private int score; public Student(String name, int age, int score) { this。name = name; this。age = age; this。score = score; } public String getName() { return name; } public void setName(String name) { this。name = name; } public int getAge() { return age; } public void setAge(int age) { this。age = age; } public int getScore() { return score; } public void setScore(int score) { this。score = score; } @Override public String toString() { return “Student{” + “name=‘” + name + ’\‘’ + “, age=” + age + “, score=” + score + ‘}’; }}

1。聚合操作

當我們使用 Stream 流處理資料後,可以像資料庫的聚合函式一樣對某個欄位進行操作。比如獲取最大值,獲取最小值,求總和,求平均值,統計數量等操作。

//最大值Collectors。maxBy();//最小值Collectors。minBy();//總和Collectors。summingInt();/Collectors。summingDouble();/Collectors。summingLong();//平均值Collectors。averagingInt();/Collectors。averagingDouble();/Collectors。averagingLong();//總個數Collectors。counting();

示例如下:

/** * Stream流資料——聚合操作 * 備註:切記Stream流只能被消費一次,流就失效了 * 如下只是示例程式碼 * @author liuzebiao */public class CollectDataToArray{ public static void main(String[] args) { Stream studentStream = Stream。of( new Student(“趙麗穎”, 58, 95), new Student(“楊穎”, 56, 88), new Student(“迪麗熱巴”, 56, 99), new Student(“柳巖”, 52, 77) ); //聚合操作 //獲取最大值(Stream流 max()方法亦可) //max()方法實現 //Optional max = studentStream。max((s1, s2) -> s1。getScore() - s2。getScore()); //(聚合)實現 Optional max = studentStream。collect(Collectors。maxBy((s1, s2) -> s1。getScore() - s2。getScore())); System。out。println(“最大值:”+max。get()); //獲取最小值(Stream流 min()方法亦可) //min()方法實現 //Optional min = studentStream。max((s1, s2) -> s2。getScore() - s1。getScore()); //(聚合)實現 Optional min = studentStream。collect(Collectors。minBy((s1, s2) -> s1。getScore() - s2。getScore())); System。out。println(“最小值:”+min。get()); //求總和(使用Stream流的map()和reduce()方法亦可求和) //map()和reduce()方法實現 //Integer reduce = studentStream。map(s -> s。getAge())。reduce(0, Integer::sum); //(聚合)簡化前 //Integer ageSum = studentStream。collect(Collectors。summingInt(s->s。getAge())); //(聚合)使用方法引用簡化 Integer ageSum = studentStream。collect(Collectors。summingInt(Student::getAge)); System。out。println(“年齡總和:”+ageSum); //求平均值 //(聚合)簡化前 //Double avgScore = studentStream。collect(Collectors。averagingInt(s->s。getScore())); //(聚合)使用方法引用簡化 Double avgScore = studentStream。collect(Collectors。averagingInt(Student::getScore)); System。out。println(“分數平均值:”+avgScore); //統計數量(Stream流 count()方法亦可) //count()方法實現 //long count = studentStream。count(); //(聚合)統計數量 Long count = studentStream。collect(Collectors。counting()); System。out。println(“數量為:”+count); }}

測試結果:

最大值:Student{name=‘迪麗熱巴’, age=56, score=99}最小值:Student{name=‘柳巖’, age=52, score=77}年齡總和:222分數平均值:89。75數量為:4

2。分組操作

當我們使用 Stream 流處理資料後,可以根據某個屬性來將資料進行分組。

//接收一個 Function 引數groupingBy(Function<? super T, ? extends K> classifier)

示例如下:

/** * Stream流資料——分組操作 * 備註:切記Stream流只能被消費一次,流就失效了 * 如下只是示例程式碼 * @author liuzebiao */public class CollectDataToArray{ public static void main(String[] args) { Stream studentStream = Stream。of( new Student(“趙麗穎”, 52, 56), new Student(“楊穎”, 56, 88), new Student(“迪麗熱巴”, 56, 99), new Student(“柳巖”, 52, 53) ); //1。按照具體年齡分組 Map> map = studentStream。collect(Collectors。groupingBy((s -> s。getAge()))); map。forEach((key,value)->{ System。out。println(key + “——>”+value); }); //2。按照分數>=60 分為“及格”一組 <60 分為“不及格”一組 Map> map = studentStream。collect(Collectors。groupingBy(s -> { if (s。getScore() >= 60) { return “及格”; } else { return “不及格”; } })); map。forEach((key,value)->{ System。out。println(key + “——>”+value。get()); }); //3。按照年齡分組,規約求每組的最大值最小值(規約:reducing) Map> reducingMap = studentStream。collect( Collectors。groupingBy(Student::getAge, Collectors。reducing( BinaryOperator。maxBy( Comparator。comparingInt(Student::getScore) ) ) ) ); reducingMap 。forEach((key,value)->{ System。out。println(key + “——>”+value); }); }}

測試結果:

52——>[Student{name=‘趙麗穎’, age=52, score=56}, Student{name=‘柳巖’, age=52, score=53}]56——>[Student{name=‘楊穎’, age=56, score=88}, Student{name=‘迪麗熱巴’, age=56, score=99}]————————————————————————————————————————————————-不及格——>[Student{name=‘趙麗穎’, age=52, score=56}, Student{name=‘柳巖’, age=52, score=53}]及格——>[Student{name=‘楊穎’, age=56, score=88}, Student{name=‘迪麗熱巴’, age=56, score=99}]————————————————————————————————————————————————-52——>Student{name=‘趙麗穎’, age=52, score=95}56——>Student{name=‘楊穎’, age=56, score=88}

3。多級分組操作

當我們使用 Stream 流處理資料後,可以根據某個屬性來將資料進行分組。

//接收兩個引數: 1。Function 引數 2。Collector多級分組groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream)

示例如下:

/** * Stream流資料——多級分組操作 * 備註:切記Stream流只能被消費一次,流就失效了 * 如下只是示例程式碼 * @author liuzebiao * @Date 2020-1-10 13:37 */public class CollectDataToArray{ public static void main(String[] args) { Stream studentStream = Stream。of( new Student(“趙麗穎”, 52, 95), new Student(“楊穎”, 56, 88), new Student(“迪麗熱巴”, 56, 55), new Student(“柳巖”, 52, 33) ); //多級分組 //1。先根據年齡分組,然後再根據成績分組 //分析:第一個Collectors。groupingBy() 使用的是(年齡+成績)兩個維度分組,所以使用兩個引數 groupingBy()方法 // 第二個Collectors。groupingBy() 就是用成績分組,使用一個引數 groupingBy() 方法 Map>>> map = studentStream。collect(Collectors。groupingBy(str -> str。getAge(), Collectors。groupingBy(str -> str。getScore(), Collectors。groupingBy((student) -> { if (student。getScore() >= 60) { return “及格”; } else { return “不及格”; } })))); map。forEach((key,value)->{ System。out。println(“年齡:” + key); value。forEach((k2,v2)->{ System。out。println(“\t” + v2); }); }); }}

測試結果:

年齡:52 {不及格=[Student{name=‘柳巖’, age=52, score=33}]} {及格=[Student{name=‘趙麗穎’, age=52, score=95}]}年齡:56 {不及格=[Student{name=‘迪麗熱巴’, age=56, score=55}]} {及格=[Student{name=‘楊穎’, age=56, score=88}]}

4。分割槽操作

我們在前面學習了 Stream流中資料的分組操作,我們可以根據屬性完成對資料的分組。接下來我們介紹分割槽操作,我們透過使用

Collectors。partitioningBy()

,根據返回值是否為 true,把集合分為兩個列表,一個 true 列表,一個 false 列表。

Java8 Stream流中的 collect() 方法,遠比你想象中的強大

分組和分割槽的區別就在:

分組可以有多個組。分割槽只會有兩個區( true 和 false)

//1。一個引數partitioningBy(Predicate<? super T> predicate) //2。兩個引數(多級分割槽)partitioningBy(Predicate<? super T> predicate, Collector<? super T, A, D> downstream)

示例如下:

/** * Stream流資料——多級分組操作 * 備註:切記Stream流只能被消費一次,流就失效了 * 如下只是示例程式碼 * @author liuzebiao */public class CollectDataToArray{ public static void main(String[] args) { Stream studentStream = Stream。of( new Student(“趙麗穎”, 52, 95), new Student(“楊穎”, 56, 88), new Student(“迪麗熱巴”, 56, 55), new Student(“柳巖”, 52, 33) ); //分割槽操作 Map> partitionMap = studentStream。collect(Collectors。partitioningBy(s -> s。getScore() > 60)); partitionMap。forEach((key,value)->{ System。out。println(key + “——>” + value); }); }}

測試結果:

false——>[Student{name=‘迪麗熱巴’, age=56, score=55}, Student{name=‘柳巖’, age=52, score=33}]true——>[Student{name=‘趙麗穎’, age=52, score=95}, Student{name=‘楊穎’, age=56, score=88}]

5。拼接操作

Collectors。joining() 會根據指定的連線符,將所有元素連線成一個字串。

//無引數——等價於 joining(“”);joining()//一個引數joining(CharSequence delimiter)//三個引數(字首+字尾)joining(CharSequence delimiter, CharSequence prefix,CharSequence suffix)

示例如下:

/** * Stream流資料——多級分組操作 * 備註:切記Stream流只能被消費一次,流就失效了 * 如下只是示例程式碼 * @author liuzebiao */public class CollectDataToArray{ public static void main(String[] args) { Stream studentStream = Stream。of( new Student(“趙麗穎”, 52, 95), new Student(“楊穎”, 56, 88), new Student(“迪麗熱巴”, 56, 55), new Student(“柳巖”, 52, 33) ); //拼接操作 //無參:join() String joinStr1 = studentStream。map(s -> s。getName())。collect(Collectors。joining()); System。out。println(joinStr1); //一個引數:joining(CharSequence delimiter) String joinStr2 = studentStream。map(s -> s。getName())。collect(Collectors。joining(“,”)); System。out。println(joinStr2); //三個引數:joining(CharSequence delimiter, CharSequence prefix,CharSequence suffix) String joinStr3 = studentStream。map(s -> s。getName())。collect(Collectors。joining(“—”,“^_^”,“>_<”)); System。out。println(joinStr3); }}

測試結果:

趙麗穎楊穎迪麗熱巴柳巖趙麗穎,楊穎,迪麗熱巴,柳巖^_^趙麗穎—楊穎—迪麗熱巴—柳巖>_<

相關文章

頂部