Java hashmap 不能判断重复键值的问题

想让String[]数组存入到一个map中,但是不能判断出已经存在的相同元素
图片说明
lists中的内容如下:
图片说明
最后wordsCount中包含有3个相同的(i,will):1的key-value值?
图片说明
怎样使结果为(i,will):3
新手求助

15个回答

把String数组换成一个类吧,拥有两个String属性的类,经测试可以实现,希望对你有帮助。另外可以查看一下对equals和hashcode重写的写法

public class OverHashcode {
static Map wordsCount = new HashMap<>();
static List list = new ArrayList();

public static void toMap() {
    for (LikeStringArray tempStr : list) {
        if (wordsCount.containsKey(tempStr)) {
            wordsCount.put(tempStr, wordsCount.get(tempStr) + 1);
        } else {
            wordsCount.put(tempStr, 1);
        }
    }

    for (Map.Entry<LikeStringArray, Integer> entry : wordsCount.entrySet())
        System.out.printf("%s:%d\n",  entry.getKey(), entry.getValue());
}
public static void main(String[] args) {
    list.add(new LikeStringArray("i","do"));
    list.add(new LikeStringArray("i","do"));
    list.add(new LikeStringArray("i","will"));
    list.add(new LikeStringArray("i","will"));
    list.add(new LikeStringArray("i","will"));
    list.add(new LikeStringArray("i","am"));
    toMap();

}

}

class LikeStringArray{
String id;
String name;
LikeStringArray(String id,String name){
this.id= id;
this.name = name;
}
@Override
public int hashCode() {
//返回的hash值进行比较,若equals方法返回true则hashCode方法也应该返回true
return this.name.hashCode()+this.id.hashCode();
}
@Override
public boolean equals(Object obj) {
LikeStringArray other = (LikeStringArray) obj;
//id和name都相同就返回true即是内容上的比较
if(id.equals(other.id)&&name.equals(other.name)){
return true;
}
return super.equals(obj);
}
//输出时别忘了重写toString方法
public String toString() {

    return "<"+id+","+name+">";
}

}

lppzyt
lppzyt 因为在静态方法中直接用了map和list集合,所以也得定义成static的
2 年多之前 回复
H_Targaryen
Mi4o static Map<LikeStringArray, Integer> wordsCount = new HashMap<LikeStringArray, Integer>(); static List<LikeStringArray> list = new ArrayList<LikeStringArray>();
2 年多之前 回复
H_Targaryen
Mi4o 有两条语句必须这样写才不会报错:
2 年多之前 回复

看一下containskey的方法,是怎么判断是否包含的。数组即使元素一样的,但是是不同的对象,equal返回的是false。
数组的equal方法

     public boolean equals(Object obj) {
        return (this == obj);
    }
        List<String[]> l = new ArrayList<>();
        String[] s ="a,a,a,a,a,b,b,b,c,c,c,c".split(",");
        String[] s1 ="d,e,f,d,e,d,a,a,a,a,a,b,b,b,c,c,c,c".split(",");
        String[] s2 ="a,a,a,a,a,b,b,b,c,c,c,c".split(",");
        String[] s3 ="d,e,f,d,e,d,a,a,a,a,a,b,b,b,c,c,c,c".split(",");
        l.add(s);l.add(s);l.add(s);l.add(s);
        l.add(s1);l.add(s1);
        l.add(s2);l.add(s2);
        l.add(s3);
        Map map = new HashMap<String,Integer>();
        for (String[] strings : l) {
            map.put(strings,!map.containsKey(strings) ?1 :((Integer) map.get(strings))+1);
        }
        System.err.println(map.toString());

{[Ljava.lang.String;@7852e922=2, [Ljava.lang.String;@15db9742=4, [Ljava.lang.String;@6d06d69c=2, [Ljava.lang.String;@4e25154f=1}

结论:s与s2内容一致 ,s1与s3内容一致 简单来说Object作为key的话比较的是地址、楼主上面的例子6个对象有6个地址 所以均为1

package chapter2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

static Map<String, Integer> wordsCount = new HashMap<>();
static List<String[]> lists = new ArrayList<>();

public static void toMap() {
    for (String[] temp : lists) {
        String tempStr = Arrays.toString(temp);
        if (wordsCount.containsKey(tempStr)) {
            wordsCount.put(tempStr, wordsCount.get(tempStr) + 1);
        } else {
            wordsCount.put(tempStr, 1);
        }
    }

    for (Map.Entry<String, Integer> entry : wordsCount.entrySet())
        System.out.printf("%s:%d\n",  entry.getKey(), entry.getValue());
}


public static void main(String[] args) {
    String[] a = {"i","do"};
    String[] b = {"i","do"};
    String[] c = {"i","will"};
    String[] d = {"i","will"};
    String[] e = {"i","will"};
    String[] f = {"i","am"};
    lists.add(a);
    lists.add(b);
    lists.add(c);
    lists.add(d);
    lists.add(e);
    lists.add(f);
    toMap();
}

}

给个思路:
用java.util.Set实现,set的add方法,如果对象存在返回false,例如:
Map times = new HashMap();
for(Object o : Arrays){
String key = "i"+"_" + "will";
//如果添加成功
if(set.add(key){
times.put(key, 1);
}else{
//添加失败,加1
times.put(key, times.get(key)+1);
}
}

最后的times能达到你想要的效果。

数组是比较地址是否一致。你试试取key对应的Val,结果会是null。

H_Targaryen
Mi4o 使用get方法试过,是null。但是不知道怎么使用其他方法判断key和修改val
2 年多之前 回复

建议循环判断下String[] temp中的元素

也可以建立一个自定义对象,把数组作为对象的成员变量,然后重写equals和hashcode函数就可以。

图片说明
看下实现,你就知道为什么不行了。 数组对象里即使内容相同,对象还是不等

共15条数据 1 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问