Java Comparator Methods - Java 147

Java Comparator Methods – Java 147

Java Comparator Methods

功能接口,使用 Lambda 語法,可當作其他方法的傳入參數或是引用其他方法為實例,常用於集合或陣列比較元素,傳入 2 個同型別物件參數,結果傳回 int ,可以使用 thenComparing 組合成鏈式判斷,提高了程式碼的可管理性,有助於分別進行單元測試,Comparator Java Methods 介紹常見的 compare 、 thenComparing 、 reversed 等方法,了解 Comparator 的不同操作和方法,本篇增加了範例,並透過單元測試來驗證產出結果。

o1 大於 o2 傳回 1 。
o1 等於 o2 傳回 0 。
o1 小於 o2 傳回 -1 。

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
} 

檔案目錄

./
   +- src
       +- test
       |   +- org
       |       +- ruoxue
       |           +- java_147
       |               +- comparator
       |                   +- ComparatorMethodsTest.java   

單元測試

Comparator Java Methods 提供 compare 、 thenComparing 、 reversed 條件或組合成鏈式判斷等操作 Comparator Functions in Java 。

traditional

Comparator Methods Java 使用傳統方式,實作 Comparator 接口,比對字串或數字,由小到大排序。

	public static Comparator<String> stringComparator = new Comparator<String>() {
		@Override
		public int compare(String o1, String o2) {
			return o1.compareTo(o2);
		}
	};

	public static class IntegerComparator implements Comparator<Integer> {
		@Override
		public int compare(Integer o1, Integer o2) {
			return Integer.compare(o1, o2);
		}
	};

	@Test
	public void traditional() {
		List<String> list = Arrays.asList("Orange", "Mango", "Peach");
		System.out.println(list);
		list.sort(stringComparator);
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Orange", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		IntegerComparator integerComparator = new IntegerComparator();
		Arrays.sort(array, integerComparator);
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}
[Orange, Mango, Peach]
[Mango, Orange, Peach]
[3, 1, 2]
[1, 2, 3]

comparing

Comparator Methods Java 建立集合及陣列,比對字串或數字,由小到大排序。

	@Test
	public void comparing() {
		List<String> list = Arrays.asList("Orange", "Mango", "Peach");
		System.out.println(list);
		list.sort(Comparator.comparing(String::length));
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Peach", list.get(1));
		assertEquals("Orange", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(e -> e));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}
[Orange, Mango, Peach]
[Mango, Peach, Orange]
[3, 1, 2]
[1, 2, 3]

comparingWithKeyComparator

Comparator Methods Java 建立集合及陣列,比對字串或數字,由小到大排序。

	@Test
	public void comparingWithKeyComparator() {
		List<String> list = Arrays.asList("Orange", "Mango", "Peach");
		System.out.println(list);
		list.sort(Comparator.comparing(String::toUpperCase, (o, o2) -> o.compareTo(o2)));
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Orange", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(e -> e, (i, i2) -> Integer.compare(i, i2)));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}
[Orange, Mango, Peach]
[Mango, Orange, Peach]
[3, 1, 2]
[1, 2, 3]

thenComparing

Comparator Methods Java 建立集合及陣列,使用 thenComparing 組合比對字串或數字,由小到大排序,其中若有例外拋出,將會中斷執行。

	@Test
	public void thenComparing() {
		List<String> list = Arrays.asList("Orange", "Peach", "Mango   ");
		System.out.println(list);
		list.sort(Comparator.comparing(String::trim).thenComparing(String::length));
		System.out.println(list);
		assertEquals("Mango   ", list.get(0));
		assertEquals("Orange", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(Integer::intValue).thenComparing(Integer::byteValue));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}
[Orange, Peach, Mango   ]
[Mango   , Orange, Peach]
[3, 1, 2]
[1, 2, 3]

reversed

Comparator Methods in Java 建立集合及陣列,比對字串或數字,由大到小排序。

	@Test
	public void reversed() {
		List<String> list = Arrays.asList("Mango", "Peach", "Orange");
		System.out.println(list);
		list.sort(Comparator.comparing(String::length).reversed());
		System.out.println(list);
		assertEquals("Orange", list.get(0));
		assertEquals("Mango", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 1, 2, 3 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(Integer::intValue).reversed());
		System.out.println(Arrays.toString(array));
		assertEquals(3, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(1, array[2].intValue());
	}
[Mango, Peach, Orange]
[Orange, Mango, Peach]
[1, 2, 3]
[3, 2, 1]

nullsFirst

Comparator Methods in Java 建立集合及陣列,比對字串或數字,由小到大排序, null 值排第一個, Comparator Functions in Java 提供範例參考。

	@Test
	public void nullsFirst() {
		List<String> list = Arrays.asList("Mango", "Peach", "Orange", null);
		System.out.println(list);
		Comparator<String> lengthComparator = Comparator.comparing(String::length);
		list.sort(Comparator.nullsFirst(lengthComparator));
		System.out.println(list);
		assertNull(list.get(0));
		assertEquals("Mango", list.get(1));
		assertEquals("Peach", list.get(2));
		assertEquals("Orange", list.get(3));

		Integer[] array = new Integer[] { 3, 1, 2, null };
		System.out.println(Arrays.toString(array));
		Comparator<Integer> intComparator = Comparator.comparing(e -> e);
		Arrays.sort(array, Comparator.nullsFirst(intComparator));
		System.out.println(Arrays.toString(array));
		assertNull(array[0]);
		assertEquals(1, array[1].intValue());
		assertEquals(2, array[2].intValue());
		assertEquals(3, array[3].intValue());
	}
[Mango, Peach, Orange, null]
[null, Mango, Peach, Orange]
[3, 1, 2, null]
[null, 1, 2, 3]

nullsLast

Comparator Methods in Java 建立集合及陣列,比對字串或數字,由小到大排序, null 值排最後個, Comparator Functions in Java 提供範例參考。

	@Test
	public void nullsLast() {
		List<String> list = Arrays.asList(null, "Orange", "Mango", "Peach");
		System.out.println(list);
		Comparator<String> lengthComparator = Comparator.comparing(String::length);
		list.sort(Comparator.nullsLast(lengthComparator));
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Peach", list.get(1));
		assertEquals("Orange", list.get(2));
		assertNull(list.get(3));

		Integer[] array = new Integer[] { null, 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Comparator<Integer> intComparator = Comparator.comparing(e -> e);
		Arrays.sort(array, Comparator.nullsLast(intComparator));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
		assertNull(array[3]);
	}
[null, Orange, Mango, Peach]
[Mango, Peach, Orange, null]
[null, 3, 1, 2]
[1, 2, 3, null]

ComparatorMethodsTest.java

Comparator Methods in Java 新增單元測試,驗證 Comparator Functions in Java 是否符合預期。

package org.ruoxue.java_147.comparator;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import org.junit.Test;

public class ComparatorMethodsTest {

	public static Comparator<String> stringComparator = new Comparator<String>() {
		@Override
		public int compare(String o1, String o2) {
			return o1.compareTo(o2);
		}
	};

	public static class IntegerComparator implements Comparator<Integer> {
		@Override
		public int compare(Integer o1, Integer o2) {
			return Integer.compare(o1, o2);
		}
	};

	@Test
	public void traditional() {
		List<String> list = Arrays.asList("Orange", "Mango", "Peach");
		System.out.println(list);
		list.sort(stringComparator);
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Orange", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		IntegerComparator integerComparator = new IntegerComparator();
		Arrays.sort(array, integerComparator);
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}

	@Test
	public void comparing() {
		List<String> list = Arrays.asList("Orange", "Mango", "Peach");
		System.out.println(list);
		list.sort(Comparator.comparing(String::length));
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Peach", list.get(1));
		assertEquals("Orange", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(e -> e));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}

	@Test
	public void comparingWithKeyComparator() {
		List<String> list = Arrays.asList("Orange", "Mango", "Peach");
		System.out.println(list);
		list.sort(Comparator.comparing(String::toUpperCase, (o, o2) -> o.compareTo(o2)));
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Orange", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(e -> e, (i, i2) -> Integer.compare(i, i2)));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}

	@Test
	public void thenComparing() {
		List<String> list = Arrays.asList("Orange", "Peach", "Mango   ");
		System.out.println(list);
		list.sort(Comparator.comparing(String::trim).thenComparing(String::length));
		System.out.println(list);
		assertEquals("Mango   ", list.get(0));
		assertEquals("Orange", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(Integer::intValue).thenComparing(Integer::byteValue));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
	}

	@Test
	public void reversed() {
		List<String> list = Arrays.asList("Mango", "Peach", "Orange");
		System.out.println(list);
		list.sort(Comparator.comparing(String::length).reversed());
		System.out.println(list);
		assertEquals("Orange", list.get(0));
		assertEquals("Mango", list.get(1));
		assertEquals("Peach", list.get(2));

		Integer[] array = new Integer[] { 1, 2, 3 };
		System.out.println(Arrays.toString(array));
		Arrays.sort(array, Comparator.comparing(Integer::intValue).reversed());
		System.out.println(Arrays.toString(array));
		assertEquals(3, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(1, array[2].intValue());
	}

	@Test
	public void nullsFirst() {
		List<String> list = Arrays.asList("Mango", "Peach", "Orange", null);
		System.out.println(list);
		Comparator<String> lengthComparator = Comparator.comparing(String::length);
		list.sort(Comparator.nullsFirst(lengthComparator));
		System.out.println(list);
		assertNull(list.get(0));
		assertEquals("Mango", list.get(1));
		assertEquals("Peach", list.get(2));
		assertEquals("Orange", list.get(3));

		Integer[] array = new Integer[] { 3, 1, 2, null };
		System.out.println(Arrays.toString(array));
		Comparator<Integer> intComparator = Comparator.comparing(e -> e);
		Arrays.sort(array, Comparator.nullsFirst(intComparator));
		System.out.println(Arrays.toString(array));
		assertNull(array[0]);
		assertEquals(1, array[1].intValue());
		assertEquals(2, array[2].intValue());
		assertEquals(3, array[3].intValue());
	}

	@Test
	public void nullsLast() {
		List<String> list = Arrays.asList(null, "Orange", "Mango", "Peach");
		System.out.println(list);
		Comparator<String> lengthComparator = Comparator.comparing(String::length);
		list.sort(Comparator.nullsLast(lengthComparator));
		System.out.println(list);
		assertEquals("Mango", list.get(0));
		assertEquals("Peach", list.get(1));
		assertEquals("Orange", list.get(2));
		assertNull(list.get(3));

		Integer[] array = new Integer[] { null, 3, 1, 2 };
		System.out.println(Arrays.toString(array));
		Comparator<Integer> intComparator = Comparator.comparing(e -> e);
		Arrays.sort(array, Comparator.nullsLast(intComparator));
		System.out.println(Arrays.toString(array));
		assertEquals(1, array[0].intValue());
		assertEquals(2, array[1].intValue());
		assertEquals(3, array[2].intValue());
		assertNull(array[3]);
	}
}

心得分享

Comparator Functions in Java 屬於 java.util ,常用於集合或陣列比較元素,例如:從小到大或大到小排序, 使用 Lambda 表達式能讓程式碼更加簡潔與直接,取代傳統實作接口的方法,減少了很多程式碼,大幅提高可讀性, Comparator Methods in Java 提供更清晰、更易讀且更靈活的方式來組合多個 Comparator 條件,來表示非常複雜的邏輯條件,如: compare 、 thenComparing 等,提供了幾種 Comparator 常見範例。

發佈留言