Reputation: 59
Hello I was wondering if somebody could help me with a little bit of code I'm stuck on. So I'm writing a custom comparator using lambda statements I want to do the following. If the names that return of .getName() equals to each other then I want to pick the one that is the String "Up" from .getDirection() (Its guaranteed one of them is "Up" in that case, the other is "Down"), else we will look at which one is alphabetically higher depending on the .getType().
So far I have this:
(x,y) -> x.getName().equals(y.getName()) ? //confused part : x.getType().compareTo(y.getType) );
Any help would be appreciated, thank you.
Upvotes: 3
Views: 170
Reputation: 111349
You cannot write this as a comparator.
Suppose you have these objects:
According to your logic, A1 < B2 and B2 < A3 and A3 < A1. This is a violation of the transitive property of the general contract of comparator.
Upvotes: 1
Reputation: 303
Don't try to get too greedy with terseness. Closures are nice, but the objective is not to write the least amount of code, it's to write only the code that's needed to get the job done in a way that's easily understood (well, most of the time anyway...)
(x, y) -> {
if (x.getName().equals(y.getName()) {
return "Up".equals(x.getDirection()) ? -1 : 1;
} else {
return x.getType().compareTo(y.getType());
}
}
Upvotes: 2
Reputation: 21
I created an example class, hope it can help.
package com;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author jinleizhang
*/
public class ComparatorTest {
static class Car {
String name;
boolean up;
String type;
Car(String name, boolean up, String type) {
this.name = name;
this.up = up;
this.type = type;
}
public String getName() {
return this.name;
}
public boolean isUp() {
return this.up;
}
public String getType() {
return this.type;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", up=" + up +
", type='" + type + '\'' +
'}';
}
}
public static void main(String[] args) {
Car carA = new Car("NewCar", false, "type2020");
Car carB = new Car("NewCar", true, "type2019");
Car carC = new Car("OldCar", true, "type1990");
List<Car> cars = new ArrayList<>();
cars.add(carA);
cars.add(carB);
cars.add(carC);
Collections.sort(cars, (x, y) -> {
if (x.getName().equals(y.getName())) {
return x.isUp() ? -1 : 1;
}
return x.getType().compareTo(y.getType());
});
for (var car : cars) {
System.out.println(car);
}
}
}
output
Car{name='OldCar', up=true, type='type1990'}
Car{name='NewCar', up=true, type='type2019'}
Car{name='NewCar', up=false, type='type2020'}
Upvotes: 2