【问题标题】:Can I sort an arraylist that is contained inside a hashmap (T)?我可以对包含在哈希图 (T) 中的数组列表进行排序吗?
【发布时间】:2016-03-18 01:03:06
【问题描述】:

我有一个哈希图,它包含键 - 字符串类型 - 奶酪对象数组:

public void testing(){
    HashMap<String, ArrayList<cheese>> one = new HashMap<>();
    ArrayList<cheese> two = new ArrayList<>();

    cheese seven = new cheese("59");
    cheese eight = new cheese("60");
    cheese nine = new cheese("12");
    cheese ten = new cheese("15");

    two.add(seven);
    two.add(eight);
    two.add(nine);
    two.add(ten);

    one.put("hello", two);

}

这是我的奶酪课:

public class cheese {

    String num;

    public cheese(String num){
        this.num = num;
    }


    public String getString(){
        return num;
    }
}

我想获取 ArrayList 并对 ArrayList 中的每个元素进行排序,然后将对象放回哈希映射中。

这是 java。我知道这听起来很疯狂但也很有趣!

我考虑过使用比较器和 TreeMaps,但它们似乎不适合这个问题。 任何指针都会有所帮助。

【问题讨论】:

  • 可以的,列表在地图中的时候可以直接排序;你可以做Collections.sort(one.get("hello"))
  • 试过了,它不起作用,因为数组中的东西是奶酪对象T_T,如果它们是整数或字符串值,那么它工作正常:) 感谢您的回复
  • 然后致电Collections.sort(one.get("hello"), thisCheeseComparatorIJustWrote)
  • 我在这个解决方案中看到一个问题,它使用字符串作为数字。无论如何,您都需要将其转换为数字类型,因为字符串使用字典排序。不确定你是否需要它。
  • @GDT 请不要忘记查看答案并选择其中一个有助于解决您的问题。干杯!

标签: java arrays sorting hashmap


【解决方案1】:

您可能想要做的是扩展您的 Cheese 类以实现 Comparable&lt;Cheese&gt; 接口。

但这假设您的Cheese 实例可以构成一个总订单。如果您不知道什么是总订单,我建议您先了解有关订购的更多信息。

你的可比类应该具备的基本特征:

  • 自反性
  • 反对称
  • 传递性

您可以通过以下链接了解更多信息: http://algs4.cs.princeton.edu/21elementary/

基本上,当您的Cheese 类实现Comparable 接口时,它会继承方法public int compareTo(T o);。您必须实现此方法并根据您的 Cheese 实例的状态返回负整数或 0 或正整数,根据比较的 Cheese 实例在您的总排序中小于或等于或大于。

如果您在 Cheese 中只有一个实例字段,就像您的示例中那样,那就是 num 字段,您可以按照以下方式编写一些内容:

public class Cheese implements Comparable<Cheese> {

    String num;

    public Cheese(String num){
        this.num = num;
    }

    public String getString(){
        return num;
    }

    public int compareTo(Cheese that) {
        return this.num.compareTo(that.num);
    }
}

请注意,这是一个有点退化(或幸运?)的情况,因为 Cheese 类的状态仅取决于单个 String。因此,在这种情况下,可以通过比较 num 字段轻松确定哪个更小、相等或更大。另一方面,如果您稍后使用其他字段扩展您的类,那么您应该准备修改您的 compareTo 方法以将这些字段也考虑在内并保持类遵循总排序的特性。

一个很好的做法是让您的班级受到控制,以便为所有 3 个功能(自反性、反对称、传递性)编写单元测试,当您添加新字段并且您的 compareTo 方法违反总排序时,这些功能将失败。

另外,如果您有一个 String 字段,我也会考虑使用字符串来表示奶酪。

可能排序不适合你,因为你的类之前没有实现Comparable

作为Comparable 的替代方案,您可能还希望实现Comparator 接口,这样您就可以将不同的奶酪排序策略从实际的Cheese 类中分离出来。


编辑:展示如何实现您的目标

你这么说

我想获取 ArrayList 并对其中的每个元素进行排序 ArrayList,然后将对象放回哈希映射中

然后你可以这样做(使用我上面的Cheese 类):

public void testing(){
        HashMap<String, List<Cheese>> one = new HashMap<>();
        List<Cheese> two = new ArrayList<>();

        Cheese seven = new Cheese("59");
        Cheese eight = new Cheese("60");
        Cheese nine = new Cheese("12");
        Cheese ten = new Cheese("15");

        two.add(seven);
        two.add(eight);
        two.add(nine);
        two.add(ten);

        System.out.println(two);
        assert "59".equals(two.get(0).num);
        assert "60".equals(two.get(1).num);
        assert "12".equals(two.get(2).num);
        assert "15".equals(two.get(3).num);

        Collections.sort(two);

        System.out.println(two);
        assert "12".equals(two.get(0).num);
        assert "15".equals(two.get(1).num);
        assert "59".equals(two.get(2).num);
        assert "60".equals(two.get(3).num);
        one.put("hello", two);
}

【讨论】:

  • 所以你是说解决方案是让我的奶酪类可比,当我这样做时,我将能够应用排序方法。一个类要被认为是可比的,它必须具备的三件事是,反身性、反对称性和传递性。仍然有点不确定如何实际应用这个概念(编写代码):(。感谢发帖!
  • 是的,这正是我的建议。我将更新我的答案以展示如何排序和更新 HashMap。
  • 谢谢你 Fogetti!,我不会“忘记”这个 :)
  • @GDT 还有一件事需要注意。当前的实现按字典顺序对奶酪进行排序。根据您的要求,这可能是也可能不是您想要的。如果您想按数字顺序订购奶酪,我建议您使用 Integer 字段而不是 String 字段。
【解决方案2】:

您可以简单地从 hashMap 中获取一个数组并使用 Arrays.sort 对其进行排序。不用放回去,hashmap已经有引用了。使用树集而不是数组将无需在每次添加元素时进行排序。树集是一个集合,因此如果这是一个问题,则不允许重复。

【讨论】:

    【解决方案3】:

    我假设您提供了一个最小的示例。否则,您可以在将列表放入 Map 之前对列表进行排序。

    话虽如此,您可以直接在Map 中更改可变值类型而不会出现任何问题。

    所以像下面这样的代码完全没问题:

    Map myMap = one.get("hello");
    sortMyMap(myMap);
    

    这将导致地图内的列表被排序(假设sortMyMap 对元素进行了适当的排序)。

    如果地图中的值元素是不可变的,你可以用新的put覆盖它:

    Map myMap = one.get("hello");
    Map mySortedMap = sortMyMap(myMap);
    one.put("hello", mySortedMap);
    

    请注意,在此示例中,我假设 sortMyMap 创建一个新的、已排序的映射并返回。

    【讨论】:

    • 地图的哪些功能允许我“忽略”对象类型的奶酪,以便进行排序?我可以举个例子吗?
    【解决方案4】:

    那里。这两行将对您所有的ArrayLists 进行排序。

    for(String key: one.keySet()) {
        Collections.sort(one.get(key));
    

    【讨论】:

      【解决方案5】:

      这是一个单行:

      one.values().forEach(l -> l.sort(Comparator.comparing(cheese::getString)));
      

      这意味着,使用cheese 对象的getString() 方法的结果对列表元素进行排序,对存储为名为@9​​87654324@ 的映射中的值的每个List&lt;cheese&gt; 调用sort()

      【讨论】:

        【解决方案6】:

        您可以在 Cheese 类中实现 Comparator,例如:

        public class Cheese implements Comparator<Cheese>{
        
        String num;
        
        public Cheese(String num){
            this.num = num;
        }
        
        public Cheese() {
        
        }
        
        public String getCheese(){
            return num;
        }
        
        @Override
        public int compare(Cheese o1, Cheese o2) {
        
            return o1.getCheese().compareTo(o2.getCheese());
        }
        

        然后在你的 testing() 方法之前 - one.put("hello", two); 你可以写

        Collections.sort(two, new Cheese());
        one.put("hello", two);
        

        我认为您将在 HashMap 中获得排序后的 ArrayList。希望这会有所帮助。

        【讨论】:

        • 嘿Sohal Rana,终于解决了这个问题。您的解决方案在其中发挥了重要作用,明天晚上下班后将发布解决方案! :)
        【解决方案7】:

        答案,谢谢大家;

        public class one {
        
        public void testing(){
            HashMap<String, ArrayList<cheese>> one = new HashMap<>();
            ArrayList<cheese> two = new ArrayList<>();
        
            two.add(new cheese("59"));
            two.add(new cheese("70"));
            two.add(new cheese("65"));
            two.add(new cheese("25"));
            one.put("hello", two);
        
            System.out.println(one.get("hello"));
        
            Collections.sort(two, new Comparator<cheese>() {
        
                @Override
                public int compare(cheese o1, cheese o2) {
                    // TODO Auto-generated method stub
                    return o1.getCheese().compareTo(o2.getCheese());
                }
        
            });
        
            System.out.println(one.get("hello"));
        }
        
        public String RemovingThe(){
        
            String tmp = "^(?:The)\\s(.+)$";
        
            Pattern a = Pattern.compile(tmp);
            Matcher b = a.matcher(" he cat in the hat");
        
        
            if(b.find()){
            return b.group(1);
            }else{
            String nop = "no";
            return nop;
        
            }
        
        
        }
        
        public static void main (String args[]){
            one two = new one();
            two.testing();
            System.out.println(two.RemovingThe());
            }
        }
        

        \\\\\\\\\\onetwothree////////////////

        public class cheese{
        
        String num;
        
        public cheese(String num){
            this.num = num;
        }
        
        
        public String getCheese(){
            return num;
        }
        
        public String toString(){
            return num;
        }
        
        public void setCheese(String num){
            this.num = num;
        }
        
        
        
        }
        

        【讨论】:

          猜你喜欢
          • 2021-08-22
          • 1970-01-01
          • 2017-12-13
          • 2010-10-15
          • 1970-01-01
          • 2017-05-30
          • 2019-04-25
          • 2010-09-11
          • 1970-01-01
          相关资源
          最近更新 更多