开发者

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 开发者_JAVA百科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

  • Here is working ideone Demo


Sounds like a job for Guava's Multimap types, specifically 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜