简体   繁体   中英

How can I create a sorted list of integer and string pairs?

How can I create a list (or some other type of container) of integer and strings pairs that allows duplicates in both pairs and can be sorted by the integer value?

I need to fill a container with names (string) and scoring (integer) pairs, the container must allow duplicated values in both name and scoring, and i need to sort this list by the scoring value.

I tried with a SortedMap but doesn't allow duplicated values:

SortedMap<Integer,String> sm=new TreeMap<Integer, String>();

sm.put(23, "Peter");  
sm.put(11, "Tony");  
sm.put(110, "Claire");  
sm.put(13, "ferca");  
sm.put(55, "Julian");  
sm.put(13, "Pedro");  

In this example, ferca and Pedro have the same scoring value, this is something I need to allow, but the SortedMap overwrites "ferca" with "Pedro".

What is the best container type to do this?

Since you want your collection to be ordered, I suggest you use a List and Collections.sort . If you decide to go for this approach you still have two options:

  • Create a custom Comparator that can be passed as an argument to sort , or
  • Let the auxiliary Score class implement Comparable<Score>

Here is an example and ideone demo of the latter approach:

import java.util.*;

class Score implements Comparable<Score> {
    int score;
    String name;

    public Score(int score, String name) {
        this.score = score;
        this.name = name;
    }

    @Override
    public int compareTo(Score o) {
        return score < o.score ? -1 : score > o.score ? 1 : 0;
    }
}

public class Test {

    public static void main(String[] args){
        List<Score> scores = new ArrayList<Score>();

        scores.add(new Score(23, "Peter"));  
        scores.add(new Score(11, "Tony"));  
        scores.add(new Score(110, "Claire"));  
        scores.add(new Score(13, "ferca"));  
        scores.add(new Score(55, "Julian"));  
        scores.add(new Score(13, "Pedro"));

        Collections.sort(scores);
    }
}
  1. Create a class that enclose these two field
  2. create a custom Comparator that compare two Objects based on int value.
  3. Create a list of that objects
  4. Collection.sort(); pass obj of comparator here

     class MyEntity{ int val; String name; } List<MyEntity> list = new ArrayList<MyEntity>(); list.add(new MyEntity(1,"a")); list.add(new MyEntity(4,"z")); list.add(new MyEntity(2,"x")); Collections.sort(list,new MyComparator()); class MyComparator implements Comparator<MyEntity>{ public int compare(MyEntity ob1, MyEntity ob2){ return ob1.getVal() - ob2.getVal() ; } } 

Note: This is just model to show the basic idea

听起来像是Guava的 Multimap类型的工作,特别是TreeMultimap

If you want a list, use a list...

The best option would probably be to create your own type to encapsulate the string and the integer, add your own comparison, and put them in an ArrayList<T> .

Sort it when you need to with Collections.sort .

If you don't need to allow duplicates which have the same name and score, you could use a SortedSet instead, so long as your comparison order sorts on both score and name.

After you create a holding type, an alternative structure is PriorityQueue to hold the items. This differs from Collections.sort() because the items are inserted in order, with either the high or low values rising to the top.

The only thing you have to do is write a Comparator to pass onto the PriorityQueue on instanciation, so it knows to sort the items based on the integer value.

Both this method and Collections.sort() deliver the same results with different ways of going about it. They also run in O(N log N) time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM