Java Collectors Methods - Java 147

Java Collectors Methods – Java 147

Java 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 更加便利的方法。

發佈留言