【问题标题】:Using Collections to sort values使用集合对值进行排序
【发布时间】:2012-01-21 01:07:19
【问题描述】:

使用 Collections 进行排序非常棒,对我来说比使用 Comparator 要好得多,因为我有多个相同的值,我不希望它们被扔到垃圾桶里。但是 Collections 有它自己的问题,它似乎认为重复的 2+ 组的数量比它们实际更小的计数器部分要小

示例有这些键和值("katy 1","mark 9","john 2","alice 11","josiah 22","chris 44") 并将它们排序如下

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

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

我该如何解决这个问题?

【问题讨论】:

    标签: java sorting collections compare


    【解决方案1】:

    最好的选择是重构您的代码以分隔字符串和整数。

    如果您不能或不想这样,您必须提供自己的比较器。类似的东西

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

    【讨论】:

      【解决方案2】:

      您需要编写自己的比较器。如果要将字符串作为数字进行比较,则需要将其转换为数字。否则 "22" 4。

      但是,我看不出您是如何使用默认比较器获得第一个订单的。

      【讨论】:

        【解决方案3】:

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

        class Person implements Comparable<Person >{
        
               String name;
               Integer number;
               public int compareTo(Person o) {
        
                return number.compareTo(o.number);
            }
        
        }
        

        【讨论】:

          【解决方案4】:

          检查这个例子

          编辑

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

          【讨论】:

          • 为什么要这么复杂? Integer 类完全能够执行自己的比较
          • @JohanSjöberg 是的,你是对的。其实我不知道这个谢谢你清除概念
          【解决方案5】:

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

          基本上你有两个选择:

          方案一:新建数据类型,封装名称和数字,实现按数字比较:

          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.
          

          【讨论】:

            【解决方案6】:
            1. 将数据存储为Map&lt;String, Integer&gt; - 不要将两种数据类型塞进一个字符串中。
            2. 获取条目集到列表中并对其进行排序
            3. 将排序好的条目集合放入有序的Map中

            这里有一些代码可以做到这一点:

            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}
            

            【讨论】:

              【解决方案7】:

              按升序对 $ 值进行排序。如果您需要按降序排列,请交换变量 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;
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-01-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-10-18
                • 2012-11-03
                • 2010-11-03
                • 1970-01-01
                相关资源
                最近更新 更多