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

我有一个hashmap,基本上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 具有相同的索引号,所以如果您想知道它是什么。

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

现在是提问时间

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

4

6 回答 6

4

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

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

于 2013-09-03T12:45:26.797 回答
1

您应该将 public Map<Object> map = new HashMap<Object>();字段更改为,public Map<String,Foo> map = new HashMap<String,Foo>();并且您应该将类​​的名称从 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());
            }
        }
    }

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

于 2013-09-03T13:17:00.487 回答
1

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

Set<Object> set = new HashSet();

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

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

于 2013-09-03T12:47:30.857 回答
0

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

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

  2. 接口Map有 2 个参数:Kfor key 和Vfor value。热线

public Map<Object> map = new HashMap<Object>();

无法编译。将其更改为

public Map<Object, Object> map = new HashMap<Object, Object>();

或者,最好使用实参数而不是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()

于 2013-09-03T12:52:52.160 回答
0

对我有用的解决方案是:

map.remove("key");
于 2018-07-05T03:20:11.810 回答
-1

尝试这个

if(map.containsKey(key)){
            map.remove(map.get(key));
        }
于 2013-09-03T12:50:33.920 回答