自定义HashMap的键

  用自定义的类型作为HashMap的key,必须同时重载hashCode()和equals(),才可以实现在HashMap中的查找自定义键。

  例如自定义Point类:

public class Point {
        private int x;
        private int y;

        public Point(int x,int y) {
            this.x = x;
            this.y = y;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getX() {
            return x;
        }

        public void setY(int y) {
            this.y = y;
        }

        public int getY() {
            return y;
        }

        @Override
        public String toString() {
            return "["+x+","+y+"]";
        }
}

  示例:

  clusters数据示例:<String, Set<Point>> <用户,所有簇中心坐标列表>

  Point作为Map的键:

Map<Point, Set<String>> usersOfCertainPoint = new LinkedHashMap<Point, Set<String>>();//<网格坐标, 聚类中心点为该坐标的所有用户列表>
Iterator<Map.Entry<String, Set<Point>>> iterator = clusters.entrySet().iterator();
while(iterator.hasNext()){
    Map.Entry<String, Set<Point>> entry = iterator.next();
    for(Point p : entry.getValue()){
        if(!usersOfCertainPoint.containsKey(p)){//containsKey()出错
            Set<String> userSet = new HashSet<String>();
            userSet.add(entry.getKey());
            usersOfCertainPoint.put(p, userSet);
        }else{
            usersOfCertainPoint.get(p).add(entry.getKey());
        }
    }
}

  错误输出示例:

  问题出在Point自动地继承自基类Object,所以这里使用Object的hashCode()方法生成散列码,而它默认是使用对象的地址计算散列码。因此即使是两个值相同的Point对象如[4515,-8198],因为其地址不同,所以生成的散列码不同。

  若只重载hashCode(),还是无法正常运行,必须同时重载equals()方法。在HashMap中,查找key的比较顺序为:

  1. 计算对象的hashCode,看在表中是否存在;
  2. 检查对应hashCode位置中的对象和当前对象是否相等。

  重载hashCode()和equals():

           @Override
        public boolean equals(Object o){
            if(this == o)//是否是本类的一个引用
                return true;
            if(!(o instanceof Point))
                return false;
            Point p = (Point)o;
            return (p.x == this.x) && (p.y == this.y);
        }
        @Override
        public int hashCode(){
            int result = 17;
            result = 31 * result + x;
            result = 31 * result + y;
            return result;
        }            

  正确输出示例:

时间: 2024-10-12 15:14:34

自定义HashMap的键的相关文章

[VisualStudio]_[增加自定义宏,自定义属性键值]

场景: 1. vs C++的"预处理器"里可以添加宏,但是添加之后外部程序修改并不容易,因为它添加到.vcxproj文件里了,这个文件的东西比较多,并不容易进行修改. 2.所以vs还有一个"属性管理器"的窗口,用它来自定义自己的宏,注意,这里不是指宏命令. 步骤: 1.打开属性管理窗口,菜单 视图->其他窗口->属性管理器 点击 "属性管理器" 的 "添加新项目属性表",我这里起了名字prop. 2. 双击prop

各种Map的区别,想在Map放入自定义顺序的键值对

今天做统计时需要对X轴的地区按照地区代码(areaCode)进行排序,由于在构建XMLData使用的map来进行数据统计的,所以在统计过程中就需要对map进行排序. 一.简单介绍Map 在讲解Map排序之前,我们先来稍微了解下map.map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等.其中这四者的区别如下(简单介绍): HashMap:我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接

Android HashMap按照键值排序的两种方法

有如下一个 Map 对象: HashMap<Integer, String> map = new HashMap<Integer, String>(); map.put(3,"A"); map.put(2,"B"); map.put(1,"C"); 键值排序第一种方法: Object[] key = map.keySet().toArray(); Arrays.sort(key); for(int i = 0; i<

模仿源码自定义HashMap

HashMap的实现原理简单来说是通过数组加链表实现的,结合数组查找和链表插入删除效率高,使得HashMap在数据处理方面高效.链表元素是键值对数据,数组元素为链表(源码中为链表的第一个键值对元素),同一个链表的元素是键值哈希值对数组长度取余结果相同的键值对,而它们的键值哈希码对数组长度取余结果恰好作为数组的下标,查找更为方便.详细的实现可参考这篇文章: http://blog.csdn.net/vking_wang/article/details/14166593 以下是我根据源码写的一个简单

160727、自定义hibernate主键生成策略生成字符串+数字自增长

需求:需要自增长注解如MyId0001.MyId0002.MyId0003 实现:实现这个接口org.hibernate.id.IdentifierGenerator 一.MyIdGenerator.java(测试用,实际项目中获取链接等可以改变) import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import

自定义Back返回键(实现按两次返回键退出程序)

实现机制:当用户点击物理返回键时,Activity会调用onBackPressed(),只需在Activity中复写该方法即可 以下是代码实现: 1 package com.example.qjm3662.service_learn; 2 3 import android.content.ComponentName; 4 import android.content.Intent; 5 import android.content.ServiceConnection; 6 import andr

C#基础 Dictionary存储自定义对象作为键值

程序每次向容器Dictionary中插入数据时,都会判断Key值是否已经存在,如果不存在,则插入.否则抛出异常.那么Dictionary又是如何判断Key值是否存在的呢? 请看下面的代码: class Program { static void Main(string[] args) { var dic = new Dictionary<Person, int>(); dic.Add(new Person {Name = "ABC", Age = 18}, 1); dic.

Hibernate自定义主键

Hibernate自定义主键,通过此方法可以解决一此特殊的主键ID,在了解自定义主键时,先了解下Hibernate有自带的10种生成主键方法. 1) assigned主键由外部程序负责生成,无需Hibernate参与. 推荐此种方法,在实体配置中修改如下: <id name="HId" type="java.lang.String"> <column name="H_ID" length="20" />

自定义hash键C++

参考:https://stackoverflow.com/questions/17016175/c-unordered-map-using-a-custom-class-type-as-the-key http://zh.cppreference.com/w/cpp/container/unordered_map/unordered_map https://www.cnblogs.com/chixinfushui/p/9019988.html 关于写背包问题的程序,遇到需要自定义键值的情况. 写