Sorting a Pair<String,Integer> in Java

Viewed 1231

I'm using a List<Pair<String, Integer>> and sorting according to key and value but It shows following error as non-static method getKey() cannot be referenced from a static context

My code as follows -

import javafx.util.Pair;
import java.util.*;
class Tuple
{
    // Demonstrate javafx.util.Pair class introduced in Java 8
    public static void main(String[] args)
    {
        List<Pair<String, Integer>> entries = new ArrayList<>();

        entries.add(new Pair<String,Integer>("C", 20));
        entries.add(new Pair<>("C++", 10));
        entries.add(new Pair<>("Java", 30));
        entries.add(new Pair<>("Python", 10));
        entries.add(new Pair<>("PHP", 20));
        entries.add(new Pair<>("PHP", 10));

        // Comparator<Pair<String,Integer>> c=Comparator.<Pair<String,Integer>>comparing(e->e.getKey).thenComparingInt(Pair::getValue;
        //entries.sort(c.reversed());
        // Comparator<Pair<String,Integer>> c=Comparator.<Pair<String,Integer>>comparing(e->e.getKey).thenComparingInt(Pair::getValue);
        entries.sort(Comparator.<Pair<String,Integer>>comparing(Pair::getKey).thenComparingInt(Pair::getValue));
        entries.forEach(e->System.out.println(e.getKey()+" "+e.getValue()));

    }
}


3 Answers

Compare using Pair<String,Integer>::getKey:

entries.sort(Comparator.comparing(Pair<String,Integer>::getKey) .thenComparingInt(Pair::getValue))

Comparator::comparing takes two generic parameters T and U:

static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> var0)

and you are passing one. First parameter is the type of object which you are comparing and second one is which property you are comparing. Try this :

Comparator<Pair<String, Integer>> pairComparator = Comparator.<Pair<String, Integer>, String>comparing(Pair::getKey).thenComparingInt(Pair::getValue);
entries.sort(pairComparator);

And also I would discourage to use Pair class form JavaFX for this purpose and use AbstractMap.SimpleEntry for example :

public static void main(String[] args) {
        List<AbstractMap.SimpleEntry<String, Integer>> entries = new ArrayList<>();

        entries.add(new AbstractMap.SimpleEntry<String, Integer>("C", 20));
        entries.add(new AbstractMap.SimpleEntry<>("C++", 10));
        //...

        Comparator<AbstractMap.SimpleEntry<String, Integer>> simpleEntryComparator = Comparator.<AbstractMap.SimpleEntry<String, Integer>, String>comparing(AbstractMap.Entry::getKey).thenComparingInt(AbstractMap.SimpleEntry::getValue);
        entries.sort(simpleEntryComparator);
        entries.forEach(e -> System.out.println(e.getKey() + " " + e.getValue()));
}

You had 2 issues:

  1. entries.sort(Comparator.<Pair<String, Integer>>comparing( you are specifying only one Generci type while expected are two i.e. your comparable object type and key type. Key type is missing in this case.

  2. You have not specified generic Type::getKey properly. Specify generic type there or use lambda expression.

Example, below with lambda expression & proper generic type :

 entries.sort(Comparator.<Pair<String, Integer>, String>comparing(p -> p.getKey()).thenComparingInt(Pair::getValue));

You can use JOOL library for Tuple types. It's extended support for java-8.

Related