使用集合对值进行排序

时间:2011-12-15 10:11:51

标签: java sorting collections compare

使用Collections进行排序是非常好的,对我来说比使用Comparator要好得多,因为我有多个相同的值,而且我们不会把它们扔到垃圾桶里。但是Collections有它自己的问题,它似乎认为重复的2+组的数量要小于它​​们实际的较小的对应部分

示例包含这些键和值(" katy 1","标记9"," john 2"," alice 11", " josiah 22"," chris 44")并按如下方式对其进行排序

爱丽丝11 凯蒂1 约翰2 约西亚22 克里斯44 标记9

而不是正确的顺序 凯蒂1 约翰2 标记9 爱丽丝11 约西亚22 马克44

我该如何解决这个问题?

7 个答案:

答案 0 :(得分:5)

由于您传递的是字符串,因此集合无法告诉您希望如何解释这些字符串(即按字符串中的数字排序)。你必须更明确。

您基本上有两种选择:

选项1 :创建新数据类型以封装名称和数字,并按编号实施比较:

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

然后:

 List<Person> persons = new ArrayList<Person>();
 persons.add(new Person("alice", 11));
 persons.add(new Person("katy", 1));
 // etc.
 Collections.sort(persons);

选项2 :将字符串转换为键值对并将其放在TreeMap内,这会自动保存按键排序的值:

 TreeMap<Integer, String> map = new TreeMap<Integer, String>();
 map.put(11, "alice");
 map.put(1, "katy");
 // etc.

答案 1 :(得分:2)

  1. 将数据存储为Map<String, Integer> - 不要将这两种数据类型塞入单个字符串中。
  2. 将条目设置到列表中并对其进行排序
  3. 将已排序的条目集放入有序的地图
  4. 以下是一些可以执行此操作的代码:

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

    输出:

    {katy=1, john=2, alice=11, josiah=22, chris=44}
    

答案 2 :(得分:1)

我认为你必须创建实现Comparable接口的类Person

class Person implements Comparable<Person >{

       String name;
       Integer number;
       public int compareTo(Person o) {

        return number.compareTo(o.number);
    }

}

答案 3 :(得分:1)

按升序排序$ value的逻辑。如果你需要降序,请交换变量i1和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;
}

答案 4 :(得分:0)

最好的选择是重构代码以分离String和Integers。

如果你不能,或者不想那样,你必须提供自己的比较器。像

这样的东西
@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);
}

然后您可以使用Collections.sort(List, Comparator)

List<String> list; // ...
Collections.sort(list, new YourComparator());

答案 5 :(得分:0)

您需要编写自己的比较器。如果要将String作为数字进行比较,则需要将其转换为数字。否则“22”&lt; “4”即使22> 4。

但是,我没有看到如何使用默认比较器获得第一个订单。

答案 6 :(得分:0)

检查此示例

修改

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