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 tosort
, or - Let the auxiliary
Score
class implementComparable<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);
}
}
- Create a
class
that enclose these two field - create a custom
Comparator
that compare two Objects based on int value. - Create a
list
of that objects Collection.sort();
pass obj ofcomparator
hereclass 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.
精彩评论