Saad
Saad

Reputation: 907

Sorting this Map<String, FullName> in Java

I have a Map where FullName is an object and contains another object of class Name that contains FirstName and LastName. Firstname and last names are String. (Yes i know its a bad design, but i am trying to learn sorting)

The key String is just id's such as 1,2,3,...

I want to sort based on the full name(both firstname and last name), and just return a list of id's.

This is the code i have so far, but i am getting a syntax error on the sorted portion where i am passing the comparator. And also I am pretty sure i am doing something incorrect semantically too.

List<String> listofIds = map.entrySet().stream()
            .sorted(new ValueComparator(map))
            .map(Map.Entry::getKey)
            .collect(toList());

class ValueComparator implements Comparator<String> {
    Map<String, FullName> base;

    public ValueComparator(Map<String, FullName> base) {
        this.base = base;
    }

    public int compare(String a, String b) {
        FullName fullName1 = base.get(a);
        FullName fullName2 = base.get(b);
        return(fullName1.getName().getFirstName()
               .compareTo(fullName2.getName().getFirstName()));
    }
}

Upvotes: 1

Views: 493

Answers (1)

lucasvw
lucasvw

Reputation: 1559

Your comparator is for String objects, but map.entrySet().stream() returns a stream of Entry<String, FullName> objects.

As suggested by JB in the comments, you can use the static Comparator method #comparing to quickly build a Comparator:

List<String> listofIds = map.entrySet().stream().sorted(
  Comparator.comparing(e -> e.getValue().getName().getFirstName())
).map(Map.Entry::getKey).collect(toList());

You can take advantage of Comparator being a functional interface like this:

List<String> listofIds = map.entrySet().stream().sorted(
    (e1, e2) -> e1.getValue().getName().getFirstName().compareTo(
       e2.getValue().getName().getFirstName())
).map(Map.Entry::getKey).collect(toList());

If you still want to use a Comparator object, you could use:

private static class ValueComparator implements Comparator<Entry<String, FullName>> {

  @Override
  public int compare(Entry<String, FullName> e1, Entry<String, FullName>> e2) {
    FullName fullName1 = e1.getValue();
    FullName fullName2 = e2.getValue();
    return fullName1.getName().getFirstName()
           .compareTo(fullName2.getName().getFirstName());
  }
}

Upvotes: 1

Related Questions