【问题标题】:Java removing object from hashmapJava 从 hashmap 中删除对象
【发布时间】:2013-09-03 12:42:13
【问题描述】:
public Map<Object> map = new HashMap<Object>();


map.add(new Object ("a", "b"));


public class Object {

    private String a;
    private String b;
    private String c;

    public Object(String a, String b) {
        this.a = a;
        this.a = b;
        this.c = "" + a + b + "";
    }

    public String getA() {
        return a;
    }

    public String getB() {
        return b;
    }

    public String getC() {
        return c;
    }   
}   

我有一个哈希图,基本上Object.getC() 应该是字符串中的a + b。 在其他类中,我需要获取 c 值,如果该 hashmap 集合索引具有完全相同的 c 值,它将删除索引:

public static void deleteChest() {
    for (int i = 0; i < data.size(); i++) {
        if (data.get(i).getItems().length == 0) {
            Object c = new Object(data.get(i).getA(), data.get(i).getB());
            map.remove(c);
        }
    }
}

data hashmap 应该与 map hashmap 具有相同的索引号,所以如果您想知道它是什么。

基本上,我循环遍历所有数据哈希图项(获取 A、B,然后匹配 C 是否在另一个哈希图(映射)内)。

现在是提问时间

如何检查一个对象是否包含(存在)或删除它(不是通过索引,而是通过键)?我该怎么做(上面的例子)。

【问题讨论】:

  • 请不要给你的班级打电话Object。你甚至都不知道是什么击中了你。
  • 这只是一个例子。 @SotiriosDelimanolis - 但感谢知道。
  • 离题:使用 Object 作为类名不是一个好主意。最好不要使用 JDK 中已经存在的类的名称
  • @JonyKale,改用Foo
  • 您确定您使用的是 HashMap 而不是 HashSet?

标签: java hashmap


【解决方案1】:

您应该为您的类定义equalshashCode 方法。

否则,您将退回到检查对象身份的默认实现,即如果两个引用指向相同的内存位置,而不是指向包含相同数据的两个对象。

【讨论】:

    【解决方案2】:

    您遇到的第一个问题是 Map 使用键来检索值。

    Set&lt;Object&gt; set = new HashSet();

    然后,当您使用 Set 或 Map 时,您的类必须覆盖 hashcodeequals 方法。如果不这样做,Set 将不知道如何正确比较它们,执行任何操作。

    这就是为什么当你创建一个新的 Object(a,b,c) 时它设置找不到它们,因为它使用与类型成员无关的哈希码的默认值。

    【讨论】:

      【解决方案3】:

      您应该将public Map&lt;Object&gt; map = new HashMap&lt;Object&gt;(); 字段更改为public Map&lt;String,Foo&gt; map = new HashMap&lt;String,Foo&gt;();,并且您应该将类​​的名称从 Object 更改为 Foo 作为“mre”建议。

      Foo 类

      public class Foo {
      
          private String a;
          private String b;
          private String c;
      
          public Foo(String a, String b) {
              this.a = a;
              this.a = b;
              this.c = getKey();
          }
      
          public String getA() {
              return a;
          }
      
          public String getB() {
              return b;
          }
      
          public String getC() {
              return c;
          }   
      
          public String getKey() {
              return "" + a + b + "";
          }
      
          @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + ((a == null) ? 0 : a.hashCode());
          result = prime * result + ((b == null) ? 0 : b.hashCode());
          result = prime * result + ((c == null) ? 0 : c.hashCode());
          return result;
      }
      
      @Override
      public boolean equals(Object obj) {
          if (this == obj)
              return true;
          if (obj == null)
              return false;
          if (getClass() != obj.getClass())
              return false;
          Foo other = (Foo) obj;
          if (a == null) {
              if (other.a != null)
                  return false;
          } else if (!a.equals(other.a))
              return false;
          if (b == null) {
              if (other.b != null)
                  return false;
          } else if (!b.equals(other.b))
              return false;
          if (c == null) {
              if (other.c != null)
                  return false;
          } else if (!c.equals(other.c))
              return false;
          return true;
      }
      }  
      

      您可以按如下方式在地图中添加对象

      map.put(new Foo("a", "b").getKey(),new Foo("a", "b"));
      

      现在你的deleteChest() 方法会像

      public static void deleteChest() {
              Foo foo = null;  
              for (int i = 0; i < data.size(); i++) {
                  foo =  map.get(new Foo(data.get(i).getA(), data.get(i).getB()).getKey())   
                  if( foo != null) {
                      map.remove(foo.getKey());
                  }
              }
          }
      

      希望这能解决您的问题..

      【讨论】:

        【解决方案4】:

        首先,由于多种原因,您的代码无法编译。

        1. 你给你的班级打电话Object。仅供参考java.lang.Object 是所有类的基类。由于 realObject 属于包 java.lang 您不必导入它,因此它始终可用。我不明白编译器如何解决这种命名冲突。

        2. 接口 Map 有 2 个参数:K 用于键,V 用于值。有线路

        public Map&lt;Object&gt; map = new HashMap&lt;Object&gt;();

        无法编译。改成

        public Map&lt;Object, Object&gt; map = new HashMap&lt;Object, Object&gt;();

        或者,最好使用实参而不是Object

        1. Map 接口具有接受 2 个参数的 put 方法。因此,以下行也无法编译。

        map.add(new Object ("a", "b"));

        如果您想使用关联字符串组的映射,请使用如下代码:

        Map<String, String> map = new HashMap<>();
        map.put("a", "b");
        

        使用键删除值:

        map.remove("a");
        

        要检索值,请使用String v = map.get("a")

        要检索所有值,请使用map.keySet()map.entrySet()

        【讨论】:

        • 假设我想要 我可以执行 map.remove(map.get(0).getC()) 以便打印密钥吗? 0 = 索引
        【解决方案5】:

        对我有用的解决方案是:

        map.remove("key");
        

        【讨论】:

          【解决方案6】:

          试试这个

          if(map.containsKey(key)){
                      map.remove(map.get(key));
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-05
            • 2011-06-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多