Koreanwest
Koreanwest

Reputation: 59

How Do You Write A Custom Java Comparator For A Specific String?

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

Answers (3)

Joni
Joni

Reputation: 111349

You cannot write this as a comparator.

Suppose you have these objects:

  • A1: Name: A Direction: Down Type: 1
  • A3: Name: A Direction: Up Type: 3
  • B2: Name: B Direction: Up Type: 2

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

Jonathan Locke
Jonathan Locke

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

Jinlei Zhang
Jinlei Zhang

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

Related Questions