H_Targaryen
Mi4o
2017-08-01 03:55
采纳率: 60%
浏览 3.1k
已采纳

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

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

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

15条回答 默认 最新

  • lppzyt
    lppzyt 2017-08-01 06:59
    已采纳

    把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+">";
    }
    

    }

    点赞 评论
  • u011212427
    Maybebane 2017-08-01 04:40

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

         public boolean equals(Object obj) {
            return (this == obj);
        }
    
    点赞 评论
  • maozhr720
    毛志荣 2017-08-01 05:01

    给个思路:
    用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);
    }
    }

    点赞 评论
  • maozhr720
    毛志荣 2017-08-01 05:02

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

    点赞 评论
  • qq_35553864
    阿卡阿卡 2017-08-01 05:06

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

    点赞 评论
  • zy841958835
    cloudyzhao 2017-08-01 05:08

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

    点赞 评论
  • qq_35553864
    阿卡阿卡 2017-08-01 05:09

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

    点赞 评论
  • wlq199101
    wlq199101 2017-08-01 05:13
            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

    点赞 评论
  • MaoTongBin
    MaoTongBin 2017-08-01 05:20

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

    }

    点赞 评论
  • MaoTongBin
    MaoTongBin 2017-08-01 05:23

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

    点赞 评论
  • Create_Myths
    Magical_dream 2017-08-01 05:23

    <图片说明>

    点赞 评论
  • Create_Myths
    Magical_dream 2017-08-01 05:27

    HashMap是按照键排重的,但是,后添加的会覆盖前面添加的

    点赞 评论
  • MaoTongBin
    MaoTongBin 2017-08-01 05:30

    你是没办法对String进行继承,重写方法的,因为String 被定义成fianl 。 你可以新建一个类,把String[] 作为其中的一个属性。然后重写这个类的 equals,compareTo,hashCode方法。让后将这个类作为map的key,我没有测试,感兴趣你可以研究一下。
    图片说明

    点赞 评论
  • qq_35473951
    霸王横千秋 2017-08-01 05:49

    集合Set是存放不重复的元素的。http://blog.csdn.net/qq_35473951/article/details/54136744

    点赞 评论
  • u011315960
    珠穆朗玛小王子 2017-08-01 06:25

    首先你不需要判断containsKey,因为HashMap内部值只允许key和value一一对应(这是基本概念),如果以对象作为key,是以对象的hashCode作为计算的,所以如果你想要判断两个不同对象是否相等,需要重写equals和hashCode方法。

    点赞 评论

相关推荐