Java 如何使用两个键(键对、值)创建HashMap?

Java 如何使用两个键(键对、值)创建HashMap?,java,hash,hashmap,hashcode,Java,Hash,Hashmap,Hashcode,我有一个二维整数数组。我想把它们放到一个HashMap中。但是我想基于数组索引访问HashMap中的元素。比如: 对于[2][5],map.get(2,5),它返回与该键关联的值。但是我如何用一对键创建hashMap呢?或者通常,多个键:Map有两种可能。或者使用组合键: class MyKey { int firstIndex; int secondIndex; // important: override hashCode() and equals() } 或一张地

我有一个二维整数数组。我想把它们放到一个HashMap中。但是我想基于数组索引访问HashMap中的元素。比如:


对于[2][5],
map.get(2,5)
,它返回与该键关联的值。但是我如何用一对键创建hashMap呢?或者通常,多个键:
Map有两种可能。或者使用组合键:

class MyKey {
    int firstIndex;
    int secondIndex;
    // important: override hashCode() and equals()
}
或一张地图:

Map<Integer, Map<Integer, Integer>> myMap;
Map-myMap;

创建一个表示复合键的值类,例如:

class Index2D {
  int first, second;

  // overrides equals and hashCode properly here
}
注意正确覆盖
equals()
hashCode()
。如果这看起来像很多工作,你可以考虑一些现成的通用容器,如Apache CAMON提供的<代码>配对/代码>。
这里也有很多,还有其他的想法,比如使用番石榴,虽然允许键有不同的类型,但在你的情况下,这可能是过分的(内存使用和复杂性),因为我知道你的键都是整数

使用
作为
哈希映射
的键。JDK没有Pair,但您可以使用第三方Librarray,如或编写自己的Pair类型。

有几个选项:

二维 地图 在这里,实现
equals()
hashCode()
是至关重要的。然后,您只需使用:

Map<Key, V> map = //...
番石榴 但从性能的角度来看,以及从可读性和正确性的角度来看,这都很糟糕(实施列表大小并非易事)


也许可以看看Scala,其中有元组和
case
类(将整个
类替换为一个线性项)。

不能有一个包含多个键的哈希映射,但可以有一个以多个参数为键的对象

创建一个名为Index的对象,该对象采用x和y值

public class Index {

    private int x;
    private int y;

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

    @Override
    public int hashCode() {
        return this.x ^ this.y;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Index other = (Index) obj;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }
}

然后让您的
HashMap
获得结果:

如果它们是两个整数,您可以尝试一个快速而肮脏的技巧:
Map
使用键作为
i+“#”+j


如果密钥
i+“#”+j
j+“#”+i
相同,请尝试
min(i,j)+“#”+max(i,j)

在创建自己的密钥对对象时,您应该面对一些事情

首先,您应该了解如何实现
hashCode()
equals()
。你需要这样做

其次,在实现
hashCode()
时,请确保您了解它的工作原理。给定的用户示例

public int hashCode() {
    return this.x ^ this.y;
}
实际上是你能做的最糟糕的实现之一。原因很简单:你有很多相同的哈希!而
hashCode()
应该返回int值,这些int值通常很少,最好是唯一的。使用类似以下内容:

public int hashCode() {
  return (X << 16) + Y;
}
public class Key {

  public final int X;
  public final int Y;

  public Key(final int X, final int Y) {
    this.X = X;
    this.Y = Y;
  }

  public boolean equals (final Object O) {
    if (!(O instanceof Key)) return false;
    if (((Key) O).X != X) return false;
    if (((Key) O).Y != Y) return false;
    return true;
  }

  public int hashCode() {
    return (X << 16) + Y;
  }

}
所以最终你的关键类是这样的:

public int hashCode() {
  return (X << 16) + Y;
}
public class Key {

  public final int X;
  public final int Y;

  public Key(final int X, final int Y) {
    this.X = X;
    this.Y = Y;
  }

  public boolean equals (final Object O) {
    if (!(O instanceof Key)) return false;
    if (((Key) O).X != X) return false;
    if (((Key) O).Y != Y) return false;
    return true;
  }

  public int hashCode() {
    return (X << 16) + Y;
  }

}
公共类密钥{
公共最终int X;
公共财政;
公钥(最终整数X,最终整数Y){
这个.X=X;
这个。Y=Y;
}
公共布尔等于(最终对象O){
如果(!(O instanceof Key))返回false;
如果((键)O).X!=X)返回false;
如果((键)O).Y!=Y)返回false;
返回true;
}
公共int hashCode(){

return(X在公共集合中实现

您可以创建如下关键对象:

public int hashCode() {
  return (X << 16) + Y;
}
public class Key {

  public final int X;
  public final int Y;

  public Key(final int X, final int Y) {
    this.X = X;
    this.Y = Y;
  }

  public boolean equals (final Object O) {
    if (!(O instanceof Key)) return false;
    if (((Key) O).X != X) return false;
    if (((Key) O).Y != Y) return false;
    return true;
  }

  public int hashCode() {
    return (X << 16) + Y;
  }

}
公共类映射键{

public  Object key1;
public Object key2;

public Object getKey1() {
    return key1;
}

public void setKey1(Object key1) {
    this.key1 = key1;
}

public Object getKey2() {
    return key2;
}

public void setKey2(Object key2) {
    this.key2 = key2;
}

public boolean equals(Object keyObject){

    if(keyObject==null)
        return false;

    if (keyObject.getClass()!= MapKey.class)
        return false;

    MapKey key = (MapKey)keyObject;

    if(key.key1!=null && this.key1==null)
        return false;

    if(key.key2 !=null && this.key2==null)
        return false;

    if(this.key1==null && key.key1 !=null)
        return false;

    if(this.key2==null && key.key2 !=null)
        return false;

    if(this.key1==null && key.key1==null && this.key2 !=null && key.key2 !=null)
        return this.key2.equals(key.key2);

    if(this.key2==null && key.key2==null && this.key1 !=null && key.key1 !=null)
        return this.key1.equals(key.key1);

    return (this.key1.equals(key.key1) && this.key2.equals(key2));
}

public int hashCode(){
    int key1HashCode=key1.hashCode();
    int key2HashCode=key2.hashCode();
    return key1HashCode >> 3 + key2HashCode << 5;
}
公共对象键1;
公共对象键2;
公共对象getKey1(){
返回键1;
}
公共无效设置键1(对象键1){
此参数为0.key1=key1;
}
公共对象getKey2(){
返回键2;
}
公共无效设置键2(对象键2){
这个.key2=key2;
}
公共布尔等于(对象键对象){
if(keyObject==null)
返回false;
if(keyObject.getClass()!=MapKey.class)
返回false;
MapKey key=(MapKey)keyObject;
if(key.key1!=null&&this.key1==null)
返回false;
if(key.key2!=null&&this.key2==null)
返回false;
if(this.key1==null&&key.key1!=null)
返回false;
if(this.key2==null&&key.key2!=null)
返回false;
if(this.key1==null&&key.key1==null&&this.key2!=null&&key.key2!=null)
返回此.key2.equals(key.key2);
if(this.key2==null&&key.key2==null&&this.key1!=null&&key.key1!=null)
返回此.key1.equals(key.key1);
返回(this.key1.equals(key.key1)和&this.key2.equals(key2));
}
公共int hashCode(){
int key1HashCode=key1.hashCode();
int key2HashCode=key2.hashCode();

return key1HashCode>>3+key2HashCode您也可以使用番石榴表实现此功能

表表示一个特殊的映射,其中可以以组合方式指定两个键以引用单个值。这类似于创建映射的映射

//create a table
  Table<String, String, String> employeeTable = HashBasedTable.create();

  //initialize the table with employee details
  employeeTable.put("IBM", "101","Mahesh");
  employeeTable.put("IBM", "102","Ramesh");
  employeeTable.put("IBM", "103","Suresh");

  employeeTable.put("Microsoft", "111","Sohan");
  employeeTable.put("Microsoft", "112","Mohan");
  employeeTable.put("Microsoft", "113","Rohan");

  employeeTable.put("TCS", "121","Ram");
  employeeTable.put("TCS", "122","Shyam");
  employeeTable.put("TCS", "123","Sunil");

  //get Map corresponding to IBM
  Map<String,String> ibmEmployees =  employeeTable.row("IBM");
//创建一个表
Table employeeTable=HashBasedTable.create();
//使用员工详细信息初始化表
employeeTable.put(“IBM”、“101”、“Mahesh”);
employeeTable.put(“IBM”、“102”、“Ramesh”);
雇员表.put(“IBM”、“103”、“Suresh”);
employeeTable.put(“Microsoft”、“111”、“Sohan”);
employeeTable.put(“微软”、“112”、“默翰”);
employeeTable.put(“微软”、“113”、“罗汉”);
雇员表。put(“TCS”、“121”、“Ram”);
可雇佣的。put(“TCS”、“122”、“Shyam”);
雇员表。put(“TCS”、“123”、“Sunil”);
//获取对应于IBM的映射
Map IBMememployees=employeeTable.row(“IBM”);

我们可以创建一个类来传递多个键或值,该类的对象可以用作map中的参数

import java.io.BufferedReader; 
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

 public class key1 {
    String b;
    String a;
    key1(String a,String b)
    {
        this.a=a;
        this.b=b;
    }
  }

public class read2 {

private static final String FILENAME = "E:/studies/JAVA/ReadFile_Project/nn.txt";

public static void main(String[] args) {

    BufferedReader br = null;
    FileReader fr = null;
    Map<key1,String> map=new HashMap<key1,String>();
    try {

        fr = new FileReader(FILENAME);
        br = new BufferedReader(fr);

        String sCurrentLine;

        br = new BufferedReader(new FileReader(FILENAME));

        while ((sCurrentLine = br.readLine()) != null) {
            String[] s1 = sCurrentLine.split(",");
            key1 k1 = new key1(s1[0],s1[2]);
            map.put(k1,s1[2]);
        }
        for(Map.Entry<key1,String> m:map.entrySet()){  
            key1 key = m.getKey();
            String s3 = m.getValue();
               System.out.println(key.a+","+key.b+" : "+s3);  
              }  
  //            }   
        } catch (IOException e) {

        e.printStackTrace();

    } finally {

        try {

            if (br != null)
                br.close();

            if (fr != null)
                fr.close();

        } catch (IOException ex) {

            ex.printStackTrace();

        }

    }

    }

 }
导入java.io.BufferedReader;
导入java.io.FileReader;
导入java.io.IOException;
导入java.util.*;
公共类密钥1{
b串;
字符串a;
键1(字符串a、字符串b)
{
这个a=a;
这个.b=b;
}
}
公开课阅读2{
私有静态最终字符串FILENAME=“E:/studies/JAVA/ReadFile_Project/nn.txt”;
公共静态void main(字符串[]args){
BufferedReader br=null;
FileReader fr=null;
Map Map=newhashmap();
试一试{
fr=新文件读取器(文件名);
br=新的缓冲区
public class Key {

  public final int X;
  public final int Y;

  public Key(final int X, final int Y) {
    this.X = X;
    this.Y = Y;
  }

  public boolean equals (final Object O) {
    if (!(O instanceof Key)) return false;
    if (((Key) O).X != X) return false;
    if (((Key) O).Y != Y) return false;
    return true;
  }

  public int hashCode() {
    return (X << 16) + Y;
  }

}
public  Object key1;
public Object key2;

public Object getKey1() {
    return key1;
}

public void setKey1(Object key1) {
    this.key1 = key1;
}

public Object getKey2() {
    return key2;
}

public void setKey2(Object key2) {
    this.key2 = key2;
}

public boolean equals(Object keyObject){

    if(keyObject==null)
        return false;

    if (keyObject.getClass()!= MapKey.class)
        return false;

    MapKey key = (MapKey)keyObject;

    if(key.key1!=null && this.key1==null)
        return false;

    if(key.key2 !=null && this.key2==null)
        return false;

    if(this.key1==null && key.key1 !=null)
        return false;

    if(this.key2==null && key.key2 !=null)
        return false;

    if(this.key1==null && key.key1==null && this.key2 !=null && key.key2 !=null)
        return this.key2.equals(key.key2);

    if(this.key2==null && key.key2==null && this.key1 !=null && key.key1 !=null)
        return this.key1.equals(key.key1);

    return (this.key1.equals(key.key1) && this.key2.equals(key2));
}

public int hashCode(){
    int key1HashCode=key1.hashCode();
    int key2HashCode=key2.hashCode();
    return key1HashCode >> 3 + key2HashCode << 5;
}
//create a table
  Table<String, String, String> employeeTable = HashBasedTable.create();

  //initialize the table with employee details
  employeeTable.put("IBM", "101","Mahesh");
  employeeTable.put("IBM", "102","Ramesh");
  employeeTable.put("IBM", "103","Suresh");

  employeeTable.put("Microsoft", "111","Sohan");
  employeeTable.put("Microsoft", "112","Mohan");
  employeeTable.put("Microsoft", "113","Rohan");

  employeeTable.put("TCS", "121","Ram");
  employeeTable.put("TCS", "122","Shyam");
  employeeTable.put("TCS", "123","Sunil");

  //get Map corresponding to IBM
  Map<String,String> ibmEmployees =  employeeTable.row("IBM");
import java.io.BufferedReader; 
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

 public class key1 {
    String b;
    String a;
    key1(String a,String b)
    {
        this.a=a;
        this.b=b;
    }
  }

public class read2 {

private static final String FILENAME = "E:/studies/JAVA/ReadFile_Project/nn.txt";

public static void main(String[] args) {

    BufferedReader br = null;
    FileReader fr = null;
    Map<key1,String> map=new HashMap<key1,String>();
    try {

        fr = new FileReader(FILENAME);
        br = new BufferedReader(fr);

        String sCurrentLine;

        br = new BufferedReader(new FileReader(FILENAME));

        while ((sCurrentLine = br.readLine()) != null) {
            String[] s1 = sCurrentLine.split(",");
            key1 k1 = new key1(s1[0],s1[2]);
            map.put(k1,s1[2]);
        }
        for(Map.Entry<key1,String> m:map.entrySet()){  
            key1 key = m.getKey();
            String s3 = m.getValue();
               System.out.println(key.a+","+key.b+" : "+s3);  
              }  
  //            }   
        } catch (IOException e) {

        e.printStackTrace();

    } finally {

        try {

            if (br != null)
                br.close();

            if (fr != null)
                fr.close();

        } catch (IOException ex) {

            ex.printStackTrace();

        }

    }

    }

 }
   DoubleKeyHashMap<Integer, Integer, String> doubleKeyHashMap1 = new 
   DoubleKeyHashMap<Integer, Integer, String>();

   DoubleKeyHashMap<String, String, String> doubleKeyHashMap2 = new 
   DoubleKeyHashMap<String, String, String>();