compareTo_equals

compareTo 와 equals 를 동시에 사용할 수는 없을까?

given#

RegisteredPrice 클래스는 price 와 registerDate 를 멤버변수로 가지고 있습니다.

public class RegisteredPrice {
private final Price price;
private final DateVO registeredDate;
public static int sortByRegisteredDate(RegisteredPrice registeredPrice, RegisteredPrice anotherRegisteredPrice) {
return registeredPrice.registeredDate.compareTo(anotherRegisteredPrice.registeredDate);
}
}

VariablePrices 클래스는 RegisteredPrice 클래스를 Set 의 타입으로 사용합니다.

public class VariablePrices {
private final Set<RegisteredPrice> variablePrices;
public static VariablePrices of() {
return new VariablePrices(new HashSet<>());
}
public VariablePrices orderByTime() {
return variablePrices.stream()
.sorted(RegisteredPrice::sortByRegisteredDate)
.collect(Collectors.collectingAndThen(Collectors.toSet(),
VariablePrices::of));
}
}

when#

다음과 같이 VariablePrices 의 set 에 add 를 합니다.

VariablePrices variablePrices = VariablePrices.of();
DateVO DateVO1 = DateVO.of(LocalDate.of(2022, 1, 1));
DateVO DateVO2 = DateVO.of(LocalDate.of(2022, 1, 2));
DateVO DateVO3 = DateVO.of(LocalDate.of(2022, 1, 3));
DateVO DateVO4 = DateVO.of(LocalDate.of(2022, 1, 4));
variablePrices.add(RegisteredPrice.of(Price.of(1100), DateVO1)); // 1
variablePrices.add(RegisteredPrice.of(Price.of(1200), DateVO3)); // 2
variablePrices.add(RegisteredPrice.of(Price.of(1300), DateVO4)); // 3
variablePrices.add(RegisteredPrice.of(Price.of(1400), DateVO2)); // 4
variablePrices.add(RegisteredPrice.of(Price.of(1400), DateVO2)); // 5
variablePrices.add(RegisteredPrice.of(Price.of(1400), DateVO1)); // 6
System.out.printf(variablePrices.orderByTime().toString());

then#

  1. 4 와 5는 값 price 와 date 가 같기 때문에 5는 set 에서 제외 되어야 합니다.
  2. Date 순으로 정렬되어야 하기 때문에 1 -> 6 -> 4 -> 2 -> 3 순으로 출력되어야 합니다.

(variablePrices 에서 조합되는 클래스들은 모두 equals 와 hash 를 override 하였습니다.)

Error#

커밋 전에, Comparable 을 RegisteredPrice 에서 구현을 하였지만, then.1 을 위해 equals 를 사용하고, then.2 를 위해 compareTo 를 override 하였습니다.

equals 에서는 price 와 Date 를 비교, compareTo 에서는 registeredDate 비교

그러나 컬렉션들은 compareTo 를 사용하기 때문에, equal 는 무시 되었습니다. 그 결과, 순서는 기대한 바와 같았지만, 4,5번이 중복으로 들어가게 되었습니다.

두번째 방법으로, Comparable 을 구현하지 않고 Comparator 함수형 인터페이스를 작성하였는데요, 첫번째 방법과 똑같은 결과를 얻었습니다.

then 을 만족하기 위해서는 어떤 방식으로 구조를 짜면 좋을까요?

Solve#

TreeMap 으로 타입을 변경하여 다음과 같이 아이디에이션을 하게 되었습니다.

image

Last updated on