Using Collections to sort values

人盡茶涼 提交于 2019-12-12 16:09:13

问题


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?


回答1:


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.



回答2:


  1. Store the data as a Map<String, Integer> - don't cram the two data types into a single String.
  2. Get the entry set into a list and sort it
  3. Put the sorted entry set into a ordered Map

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}



回答3:


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);
    }

}



回答4:


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;
}



回答5:


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.




回答6:


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());



回答7:


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());
}


来源:https://stackoverflow.com/questions/8518359/using-collections-to-sort-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!