Table of Contents
ToggleJava 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 常見範例。