Comparator 사용 상세 및 일부 코드 분석
11916 단어 자바
1.소개
Comparator 안의 방법 은 우 리 는 몇 가지 유형 으로 나 눌 수 있다.아래 의 테스트 코드 도 이 몇 가지 유형 에 따라 그 중의 일부 방법 을 테스트 하고 나머지 방법 은 유사 하 므 로 사용 하지 않 습 니 다.
comparing thenComparing,
2.테스트
package com.study.testCompare;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.*;
public class ComparatorTest {
@Test
public void testCompare() {
List personList = new ArrayList<>();
personList.add(new Person("a", new BigDecimal(12), 170));
personList.add(new Person("b", new BigDecimal(24), 175, new Student(27)));
personList.add(new Person("c", new BigDecimal(12), 177));
personList.add(new Person("a", new BigDecimal(12), 177));
personList.add(new Person("b", new BigDecimal(54), 174, new Student(19)));
// naturalOrder
System.out.println("naturalOrder : ");
personList.sort(Comparator.naturalOrder());
personList.forEach(System.out::println);
// comparing 1.0
Optional optional = personList.stream().max(Comparator.comparing(Person::getAge));
System.out.println("comparing 1.0 : get max age " + optional.get().toString() + "
");
// comparing 2.1
optional = personList.stream().max(Comparator.comparing(Person::getName, Comparator.reverseOrder()));
System.out.println("comparing 2.1 : get min name " + optional.get().toString() + "
");
// comparing 2.2
optional = personList.stream().max(Comparator.comparing(Person::getName, String::compareTo));
System.out.println("comparing 2.2 : get max name " + optional.get().toString() + "
");
// comparing 2.3
optional = personList.stream().max(Comparator.comparing(Person::getStudent, (o1, o2) -> new Student().compare(o1, o2)));
System.out.println("comparing 2.3 : get max student.age " + optional.get().toString() + "
");
// thenComparing 1.0
System.out.println("thenComparing 1.0 : ");
personList.sort(Comparator.comparing(Person::getAge).thenComparing(Person::getHeight));
personList.forEach(System.out::println);
// thenComparing 2.0
System.out.println("thenComparing 2.0 : ");
personList.sort(Comparator.comparing(Person::getAge).thenComparing(Person::getHeight).thenComparing(Person::getName));
personList.forEach(System.out::println);
//
System.out.println(" : ");
personList.sort(Comparator.comparingInt(Person::getHeight));
personList.forEach(System.out::println);
//
System.out.println(" : ");
personList.sort(Comparator.comparingInt(Person::getHeight).reversed());
personList.forEach(System.out::println);
// nullsLast
System.out.println("nullsLast : ");
personList.sort(Comparator.nullsLast(Comparator.comparing(Person::getName)));
personList.forEach(System.out::println);
// nullsLast
System.out.println("nullsLast : ");
personList.sort(Comparator.nullsLast(Comparator.comparing(Person::getName)));
personList.forEach(System.out::println);
}
}
package com.study.testCompare;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Comparator;
@Data
public class Person implements Comparable {
private String name;
private BigDecimal age;
private Integer height;
private Student student;
public Person(String name, BigDecimal age, Integer height) {
this.name = name;
this.age = age;
this.height = height;
this.student = new Student(0);
}
public Person(String name, BigDecimal age, Integer height, Student student) {
this.name = name;
this.age = age;
this.height = height;
this.student = student;
}
@Override
public int compareTo(Object o) {
Person p1 = (Person) o;
if (this.age.equals(p1.age)) {
return p1.height - this.height;
}
return this.age.compareTo(p1.age);
}
}
@Data
class Student implements Comparator {
private int age;
public Student() {
}
public Student(int age) {
this.age = age;
}
@Override
public int compare(Object o1, Object o2) {
Student p1 = (Student) o1;
Student p2 = (Student) o2;
int result = Integer.compare(p1.age, p2.age);
result = result == 0 ? ((p1.age > p2.age) ? 1 : -1) : result;
return result;
}
}
3.소스 코드
package java.util;
import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;
/**
* ,
*/
@FunctionalInterface
public interface Comparator {
/**
*
* o1 = o2 : return 0;
* o1 > o2 : return 1;
* o1 < o2 : return -1;
*/
int compare(T o1, T o2);
/**
* equals
*/
boolean equals(Object obj);
/**
*
*/
default Comparator reversed() {
return Collections.reverseOrder(this);
}
/**
* , , ,
* @since 1.8
*/
default Comparator thenComparing(Comparator super T> other) {
Objects.requireNonNull(other);
return (Comparator & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
/**
* , , compara
* @since 1.8
*/
default Comparator thenComparing(
Function super T, ? extends U> keyExtractor,
Comparator super U> keyComparator)
{
return thenComparing(comparing(keyExtractor, keyComparator));
}
/**
* ,
* @since 1.8
*/
default > Comparator thenComparing(
Function super T, ? extends U> keyExtractor)
{
return thenComparing(comparing(keyExtractor));
}
/**
* , Int
* @since 1.8
*/
default Comparator thenComparingInt(ToIntFunction super T> keyExtractor) {
return thenComparing(comparingInt(keyExtractor));
}
/**
* , Long
* @since 1.8
*/
default Comparator thenComparingLong(ToLongFunction super T> keyExtractor) {
return thenComparing(comparingLong(keyExtractor));
}
/**
* , Double
* @since 1.8
*/
default Comparator thenComparingDouble(ToDoubleFunction super T> keyExtractor) {
return thenComparing(comparingDouble(keyExtractor));
}
/**
*
* @since 1.8
*/
public static > Comparator reverseOrder() {
return Collections.reverseOrder();
}
/**
* ( Comparable)
* @since 1.8
*/
@SuppressWarnings("unchecked")
public static > Comparator naturalOrder() {
return (Comparator) Comparators.NaturalOrderComparator.INSTANCE;
}
/**
* ,
* @since 1.8
*/
public static Comparator nullsFirst(Comparator super T> comparator) {
return new Comparators.NullComparator<>(true, comparator);
}
/**
* ,
* @since 1.8
*/
public static Comparator nullsLast(Comparator super T> comparator) {
return new Comparators.NullComparator<>(false, comparator);
}
/**
* ( , Comparator), 。 Comparator
* @since 1.8
*/
public static Comparator comparing(
Function super T, ? extends U> keyExtractor,
Comparator super U> keyComparator)
{
Objects.requireNonNull(keyExtractor);
Objects.requireNonNull(keyComparator);
return (Comparator & Serializable)
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
keyExtractor.apply(c2));
}
/**
* ( , Comparator)。
* @since 1.8
*/
public static > Comparator comparing(
Function super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
/**
* —— int
* @since 1.8
*/
public static Comparator comparingInt(ToIntFunction super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}
/**
* —— long
* @since 1.8
*/
public static Comparator comparingLong(ToLongFunction super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator & Serializable)
(c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
}
/**
* * —— double
* @since 1.8
*/
public static Comparator comparingDouble(ToDoubleFunction super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator & Serializable)
(c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
}
}
4.부분 해석 방법
원본 코드:
/**
* ( , Comparator)。
* @since 1.8
*/
public static > Comparator comparing(
Function super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
사용:
// comparing 1.0
Optional optional = personList.stream().max(Comparator.comparing(Person::getAge));
System.out.println("comparing 1.0 : max age " + optional.get().toString() + "
");
debug 를 통 해 알 수 있 듯 이 최종 소스 코드
c1
와c2
는 Person 대상 이 고 비교 할 때 IntegercompareTo
를 호출 했다.그럼 알 수 있 습 니 다keyExtractor.apply(c1) = c1.getAge()
,keyExtractor.apply(c2) = c2.getAge()
.그리고 소스 코드 에서 명확 하 게 지적 했다.Function super T, ? extends U> keyExtractor
그 중에서:T
입력 유형U
반환 유형 이기 때문에 우 리 는 lamble 을 사용 한 후에 들 어 온Person
은T
이 고getAge
는U
이다.그래서keyExtractor.apply
돌아 온 것 은Integer
유형의age
이다.최종 적 으로 대응 하 는 포장 유형compareTo
을 호출 하여 비교이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.