Table of Contents
ToggleJava Collectors Methods
是 Java 8 的 Stream API 的終端方法之一, Stream.collect() 允許對 Stream 實例中保存的資料元素執行操作,例如: 將元素重新打包到某些資料結構,並應用一些附加邏輯、連接等, 此操作的策略是通過 Collector 接口實現提供的,Java Util Collectors 提供了許多靜態方法運用,本篇增加了範例,並透過單元測試來驗證產出結果。
檔案目錄
./
+- src
+- test
| +- org
| +- ruoxue
| +- java_147
| +- collector
| +- CollectorsMethodsTest.java
單元測試
Collectors Class Java 集合類別工具,提供群組、分區、最大與最小元素等操作集合中的元素。
Fruit
建立 Fruit 類別,覆寫 toString ,定義屬性和方法,用來建立一個物件。
@NoArgsConstructor
@Getter
@Setter
@Builder
public static class Fruit {
private String name;
private double quantity;
private int type;
public Fruit(String name, double quantity, int type) {
this.name = name;
this.quantity = quantity;
this.type = type;
}
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.JSON_STYLE);
builder.appendSuper(super.toString());
builder.append("name", name);
builder.append("quantity", quantity);
builder.append("type", type);
return builder.toString();
}
}
maxBy
Collectors Class Java 建立一個 List ,內有三個元素,根據提供的 Comparator 實例,傳回 Stream 的最大元素。
@Test
public void maxBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Optional<String> result = list.stream().collect(Collectors.maxBy(Comparator.naturalOrder()));
System.out.println(result);
assertEquals("Melon", result.get());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", -1, 3),
new Fruit("Fig", 3, 1));
Optional<Fruit> fruit = fruitList.stream().collect(Collectors.maxBy(Comparator.comparing(Fruit::getName)));
System.out.println(fruit);
assertEquals("Melon", fruit.get().getName());
}
Optional[Melon]
Optional[{"name":"Melon","quantity":-1.0,"type":3}]
minBy
Collectors Class Java 建立一個 List ,內有三個元素,根據提供的 Comparator 實例,傳回 Stream 的最小元素。
@Test
public void minBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Optional<String> result = list.stream().collect(Collectors.minBy(Comparator.naturalOrder()));
System.out.println(result);
assertEquals("Blueberry", result.get());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", 3, 3),
new Fruit("Fig", 2, 1));
Optional<Fruit> fruit = fruitList.stream()
.collect(Collectors.minBy(Comparator.comparingDouble(Fruit::getQuantity)));
System.out.println(fruit);
assertEquals("Fig", fruit.get().getName());
}
Optional[Blueberry]
Optional[{"name":"Fig","quantity":2.0,"type":1}]
groupingBy
Collectors Class Java 建立一個 List ,內有三個元素,根據屬性對元素分組,傳回 Map 。
@Test
public void groupingBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Map<Integer, List<String>> result = list.stream().collect(Collectors.groupingBy(String::length));
System.out.println(result);
assertEquals(1, result.get(3).size());
assertEquals(1, result.get(5).size());
assertEquals(1, result.get(9).size());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", 3, 3),
new Fruit("Fig", 2, 1));
Map<Integer, List<Fruit>> fruitResult = fruitList.stream()
.collect(Collectors.groupingBy(Fruit::getType, Collectors.toList()));
System.out.println(fruitResult);
assertEquals(2, fruitResult.get(1).size());
assertEquals(1, fruitResult.get(3).size());
}
{3=[Fig], 5=[Melon], 9=[Blueberry]}
{1=[{"name":"Blueberry","quantity":1.7976931348623157E308,"type":1}, {"name":"Fig","quantity":2.0,"type":1}], 3=[{"name":"Melon","quantity":3.0,"type":3}]}
partitioningBy
Collectors Class Java 建立一個 List ,內有三個元素,分區符合條件的元素。
@Test
public void partitioningBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Map<Boolean, List<String>> result = list.stream().collect(Collectors.partitioningBy(e -> e.length() > 3));
System.out.println(result);
assertEquals(1, result.get(Boolean.FALSE).size());
assertEquals(2, result.get(Boolean.TRUE).size());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", 3, 3),
new Fruit("Fig", 2, 1));
Map<Boolean, List<Fruit>> fruitResult = fruitList.stream()
.collect(Collectors.partitioningBy(e -> e.getName().length() > 3, Collectors.toList()));
System.out.println(fruitResult);
assertEquals(1, fruitResult.get(Boolean.FALSE).size());
assertEquals(2, fruitResult.get(Boolean.TRUE).size());
}
{false=[Fig], true=[Blueberry, Melon]}
{false=[{"name":"Fig","quantity":2.0,"type":1}], true=[{"name":"Blueberry","quantity":1.7976931348623157E308,"type":1}, {"name":"Melon","quantity":3.0,"type":3}]}
CollectorsMethodsTest.java
Collectors in Java 新增單元測試,驗證 Collectors Methods Java 是否符合預期。
package org.ruoxue.java_147.collector;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.junit.Test;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
public class CollectorsMethodsTest {
@NoArgsConstructor
@Getter
@Setter
@Builder
public static class Fruit {
private String name;
private double quantity;
private int type;
public Fruit(String name, double quantity, int type) {
this.name = name;
this.quantity = quantity;
this.type = type;
}
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.JSON_STYLE);
builder.appendSuper(super.toString());
builder.append("name", name);
builder.append("quantity", quantity);
builder.append("type", type);
return builder.toString();
}
}
@Test
public void maxBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Optional<String> result = list.stream().collect(Collectors.maxBy(Comparator.naturalOrder()));
System.out.println(result);
assertEquals("Melon", result.get());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", -1, 3),
new Fruit("Fig", 3, 1));
Optional<Fruit> fruit = fruitList.stream().collect(Collectors.maxBy(Comparator.comparing(Fruit::getName)));
System.out.println(fruit);
assertEquals("Melon", fruit.get().getName());
}
@Test
public void minBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Optional<String> result = list.stream().collect(Collectors.minBy(Comparator.naturalOrder()));
System.out.println(result);
assertEquals("Blueberry", result.get());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", 3, 3),
new Fruit("Fig", 2, 1));
Optional<Fruit> fruit = fruitList.stream()
.collect(Collectors.minBy(Comparator.comparingDouble(Fruit::getQuantity)));
System.out.println(fruit);
assertEquals("Fig", fruit.get().getName());
}
@Test
public void groupingBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Map<Integer, List<String>> result = list.stream().collect(Collectors.groupingBy(String::length));
System.out.println(result);
assertEquals(1, result.get(3).size());
assertEquals(1, result.get(5).size());
assertEquals(1, result.get(9).size());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", 3, 3),
new Fruit("Fig", 2, 1));
Map<Integer, List<Fruit>> fruitResult = fruitList.stream()
.collect(Collectors.groupingBy(Fruit::getType, Collectors.toList()));
System.out.println(fruitResult);
assertEquals(2, fruitResult.get(1).size());
assertEquals(1, fruitResult.get(3).size());
}
@Test
public void partitioningBy() {
List<String> list = Arrays.asList("Blueberry", "Melon", "Fig");
Map<Boolean, List<String>> result = list.stream().collect(Collectors.partitioningBy(e -> e.length() > 3));
System.out.println(result);
assertEquals(1, result.get(Boolean.FALSE).size());
assertEquals(2, result.get(Boolean.TRUE).size());
List<Fruit> fruitList = Arrays.asList(new Fruit("Blueberry", Double.MAX_VALUE, 1), new Fruit("Melon", 3, 3),
new Fruit("Fig", 2, 1));
Map<Boolean, List<Fruit>> fruitResult = fruitList.stream()
.collect(Collectors.partitioningBy(e -> e.getName().length() > 3, Collectors.toList()));
System.out.println(fruitResult);
assertEquals(1, fruitResult.get(Boolean.FALSE).size());
assertEquals(2, fruitResult.get(Boolean.TRUE).size());
}
}
心得分享
Collectors Methods Java 是繼承 Object 的最終類別,它提供歸約操作,例如:將元素累積到集合中、根據各種標準彙總元素等, Collectors in Java 提供了各種處理元素的方法 ,實現操作 List 、 Set 、 Map 更加便利的方法。