Reputation: 33
Using Collections to sort is nifty, a lot better for me than using Comparator since i have multiple values that are the same and i'd rather them not be just thrown out to the trash. But Collections has it's own issue, it seems to think repeating numbers of groups of 2+ to be smaller than their actual smaller counter parts
Example have these keys and values("katy 1","mark 9","john 2","alice 11","josiah 22","chris 44") and it sorts them as follows
alice 11 katy 1 john 2 josiah 22 chris 44 mark 9
Instead of the correct order katy 1 john 2 mark 9 alice 11 josiah 22 mark 44
How can i fix this?
Upvotes: 3
Views: 9714
Reputation: 62439
Since you are passing strings, the collection has no way of telling how you want these strings to be interpreted (i.e. sort by the number present inside the string). You must be more explicit.
You have two options basically:
Option 1: Create a new data type to encapsulate a name and a number and implement comparison by number:
public class Person implements Comparable<Person> {
private String name;
private int number;
public Person(String name, int number) {
this.name = name;
this.number = number;
}
public int compareTo(Person p) {
return this.number.compareTo(p.number);
}
}
Then:
List<Person> persons = new ArrayList<Person>();
persons.add(new Person("alice", 11));
persons.add(new Person("katy", 1));
// etc.
Collections.sort(persons);
Option 2: Turn the string into a key-value pair and put it inside a TreeMap
, which automatically keeps the values sorted by key:
TreeMap<Integer, String> map = new TreeMap<Integer, String>();
map.put(11, "alice");
map.put(1, "katy");
// etc.
Upvotes: 5
Reputation: 21
Sort logic for $ values in ascending order. if you need it in descending order please interchange variables i1 and i2
public static void main(String[] args) {
List<String> l_oTestList = new ArrayList<String>();
l_oTestList.add("$10000 - $12000");
l_oTestList.add("$50 - $100");
l_oTestList.add("$10000 - $12000");
l_oTestList.add("$100 - $150");
l_oTestList.add("$150 - $200");
l_oTestList.add("$200 - $250");
l_oTestList.add("$0 - $10");
l_oTestList.add("$10 - $20");
l_oTestList.add("$20 - $50");
l_oTestList.add("$250 - $500");
l_oTestList.add("$500 - $750");
l_oTestList.add("$750 - $1000");
l_oTestList.add("$1000 - $1250");
l_oTestList.add("$1250 - $10000");
List<String> l_oTestList1 = sort(l_oTestList);
System.out.println(l_oTestList1.toString());
}
private static List<String> sort(List<String> pTestList) {
Collections.sort(pTestList, new Comparator<String>() {
public int compare(String o1, String o2) {
Integer i1 = Integer.parseInt(o1.replace("$", "").substring(0,o1.indexOf("-")-2).trim());
Integer i2 = Integer.parseInt(o2.replace("$", "").substring(0,o2.indexOf("-")-2).trim());
return (i2 > i1 ? -1 : (i2 == i1 ? 0 : 1));
}
});
return pTestList;
}
Upvotes: 1
Reputation: 425033
Map<String, Integer>
- don't cram the two data types into a single String.Here's some code that will do it:
public static void main(String[] args) {
// Set up and load the map
Map<String, Integer> nameAgeMap = new HashMap<String, Integer>();
nameAgeMap.put("katy", 1);
nameAgeMap.put("chris", 44);
nameAgeMap.put("alice", 11);
nameAgeMap.put("josiah", 22);
nameAgeMap.put("john", 2);
// Create-and-load a List of entries
List<Map.Entry<String, Integer>> entries = new ArrayList<Map.Entry<String, Integer>>(nameAgeMap.entrySet());
// Sort the list using a custom Comparator that compares the ages
Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}});
// Load the entries into a Map that preserves insert order
Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
for (Map.Entry<String, Integer> entry : entries)
sortedMap.put(entry.getKey(), entry.getValue());
// All done - let's see what we got
System.out.println(sortedMap);
}
Output:
{katy=1, john=2, alice=11, josiah=22, chris=44}
Upvotes: 3
Reputation: 30855
check this example
Edit
public static void main(String arg[]){
List<String> l = Arrays.asList(new String[]{"katy 1","mark 9","john 2","alice 11","josiah 22","chris 44"});
Collections.sort(l, new Comparator<String>() {
public int compare(String x, String y) {
Integer a = Integer.parseInt(x.substring(x.indexOf(" ")).trim());
Integer b = Integer.parseInt(y.substring(y.indexOf(" ")).trim());
return a.compareTo(b);
}
});
System.out.println(l.toString());
}
Upvotes: 0
Reputation: 49187
The best option would be to refactor your code to separate String and Integers.
If you cannot, or don't want to you that, you must provide your own comparator. Something like
@Override
public int compare(String o1, String o2) {
Integer i1 = Integer.parseInt(o1.replaceAll("[^0-9]", ""));
Integer i2 = Integer.parseInt(o2.replaceAll("[^0-9]", ""));
return i1.compareTo(i2);
}
Then you can use Collections.sort(List, Comparator)
List<String> list; // ...
Collections.sort(list, new YourComparator());
Upvotes: 0
Reputation: 4185
I think you have to create class Person which implements Comparable interface
class Person implements Comparable<Person >{
String name;
Integer number;
public int compareTo(Person o) {
return number.compareTo(o.number);
}
}
Upvotes: 1
Reputation: 533510
You need to write your own comparator. If you want to compare a String as a number you need to convert it to be a number. Otherwise "22" < "4" even though 22 > 4.
However, I don't see how you get the first order with the default comparator.
Upvotes: 0