sourcecode

2개의 키(키쌍, 값)로 해시맵을 작성하려면 어떻게 해야 합니까?

copyscript 2022. 9. 3. 13:33
반응형

2개의 키(키쌍, 값)로 해시맵을 작성하려면 어떻게 해야 합니까?

2D 배열의 정수입니다.그것들을 해시맵에 넣었으면 합니다.단, 어레이 인덱스를 기반으로 HashMap에서 요소에 액세스하고 싶습니다.예를 들어 다음과 같습니다.

[ ] [ 5 의 A [ 2 ] [ 5 ]의 경우map.get(2,5)그러면 해당 키와 관련된 값이 반환됩니다.그러나 키 쌍으로 해시 맵을 만들려면 어떻게 해야 합니까?여러 키를 : 또또::::::::또::: or:::::::::: or or or 。Map<((key1, key2,..,keyN), Value), get(key1, key2, ...keyN)을 수 .

편집 : 질문을 올린 지 3년 후, 조금 더 추가하고 싶습니다.

요.NxN matrix

인덱스, " " " "i ★★★★★★★★★★★★★★★★★」j로 수 key다음과 같이 합니다.

int key = i * N + j;
//map.put(key, a[i][j]); // queue.add(key); 

할 수 .key다음과 같이 합니다.

int i = key / N;
int j = key % N;

몇 가지 옵션이 있습니다.

2차원

지도

Map<Integer, Map<Integer, V>> map = //...
//...

map.get(2).get(5);

래퍼 키 개체

public class Key {

    private final int x;
    private final int y;

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Key)) return false;
        Key key = (Key) o;
        return x == key.x && y == key.y;
    }

    @Override
    public int hashCode() {
        int result = x;
        result = 31 * result + y;
        return result;
    }

}

★★의 equals() ★★★★★★★★★★★★★★★★★」hashCode()매우 중요합니다.을 하다

Map<Key, V> map = //...

또, 다음과 같이 합니다.

map.get(new Key(2, 5));

Table 과바 출신

Table<Integer, Integer, V> table = HashBasedTable.create();
//...

table.get(2, 5);

Table는 아래에 있는 맵을 사용합니다.

N차원

한 「」에 해 주세요.Key클래스는 n차원으로 확장되는 유일한 접근법이다.을 사용하다

Map<List<Integer>, V> map = //...

가독성과 정확성(목록 크기를 강제하는 쉬운 방법이 아님)뿐만 아니라 성능 측면에서도 매우 어렵습니다.

스칼라를 보면 튜플이 있고case)Key이치노

독자적인 키쌍 오브젝트를 작성할 때는 몇 가지 문제에 직면해야 합니다.

이행을 할 때 .hashCode() ★★★★★★★★★★★★★★★★★」equals()이 작업을 수행해야 합니다.

, 시hashCode()이 기능의 구조를 이해해 주세요.된 예 " " " "

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

실제로 실행할 수 있는 최악의 구현 중 하나입니다.이유는 간단합니다. 해시가 같기 때문입니다! ★★★★★★★★★★★★★★★★.hashCode()int 값은 드물고 가장 좋은 값으로 반환해야 합니다.하다

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

이는 고속이며 -2^16 ~2^16-1(-65536 ~65535)의 키에 대해 고유한 해시를 반환합니다.이것은 거의 모든 경우에 들어맞습니다.매우 드물게 당신은 이 범위를 벗어납니다.

때, 실장할 때equals()또, 키는 오브젝트이기 때문에, 그 용도와 작성 방법에 대해서도 알고 있습니다.원인이 되는 문장이 항상 같은 결과를 가져올 경우 불필요한 작업을 수행하는 경우가 많습니다.

같은 :map.put(new Key(x,y),V);키의 참조는 비교하지 않습니다.마다 '접근하다'와 같은 것을 됩니다.map.get(new Key(x,y)); 당신의 '오빠'는equals()는 문장이 필요 없습니다.if (this == obj)그런 일은 절대 없을 거야

if (getClass() != obj.getClass()) 안에서equals()를 사용하는 것이 .if (!(obj instanceof this))이치노

XYY로 하다 제일 건equals()은 다음과

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

인덱스를 수 .X ★★★★★★★★★★★★★★★★★」Y퍼블릭 액세스레벨은 최종적이고 기밀정보가 포함되어 있지 않기 때문입니다.% %100% i100% i100% i100% i100% i100% i100% i100% % i iprivate액세스 레벨은, 캐스트 할 때, 어떠한 경우에도 올바르게 동작합니다.Object a까지Key.

기말고사에 대해 궁금하다면, 나는 어떤 값이 인스턴스화에 설정되어 있고 절대 변하지 않는다는 것을 최종 선언한다. 따라서 객체 상수이다.

해시 맵에는 여러 키를 사용할 수 없지만 여러 파라미터를 키로 하는 개체를 사용할 수 있습니다.

x 및 y 값을 사용하는 Index라는 개체를 만듭니다.

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<Index, Value>

공통 컬렉션 MultiKeyMap에 구현됨

두 가지 가능성이 있습니다.조합된 키를 사용합니다.

class MyKey {
    int firstIndex;
    int secondIndex;
    // important: override hashCode() and equals()
}

또는 지도:

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

사용하다Pair「 」의 HashMapJDK에는 페어가 없지만, http://commons.apache.org/lang 등의 서드파티 라이브러리 또는 독자적인 페어 타이프를 작성할 수 있습니다.

Java 7+에는 맵(또는 세트의 항목)의 키로 사용할 수 있는 새로운 클래스가 포함되어 있습니다.Java 9+에는,Map.entry(K k, V v) Map.Entry★★★★★★★★★★★★★★★★★★.

사용방법:

Map<Map.Entry<Integer,Integer>, Integer> map = new HashMap<>();
map.put(Map.entry(1, 2), 0);

javafx.util에도 있습니다.

Map<Pair<Integer,Integer>, Integer> map = new HashMap<>();
map.put(new Pair(1, 2), 0);

다음과 같은 복합 키를 나타내는 값 클래스를 만듭니다.

class Index2D {
  int first, second;

  // overrides equals and hashCode properly here
}

「」를 무효로 하는 .equals() ★★★★★★★★★★★★★★★★★」hashCode()올바르게 동작합니다.할 것 예: 를.Pair이치노

여기에서도 Guava's Table을 사용하는 것과 같은 유사한 질문이 많이 있습니다.다만, 키는 다른 타입으로 할 수 있습니다.이 경우, 메모리 사용이나 복잡성이 과잉이 될 가능성이 있습니다.이것은, 양쪽 모두의 키가 정수인 것을 알기 때문입니다.

두 속임수를 쓸 수: ㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴ다.Map<String, ?>를 「」로서 i+"#"+j.

가 「」인 .i+"#"+j is is is is is와 j+"#"+i 해보다min(i,j)+"#"+max(i,j).

여기에는 guava Table 구현도 사용할 수 있습니다.

Table은 하나의 값을 참조하기 위해 2개의 키를 조합하여 지정할 수 있는 특수한 맵을 나타냅니다.이것은 지도의 작성과 비슷합니다.

//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");

다음과 같은 주요 개체를 만들 수 있습니다.

공개 클래스 MapKey {

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

}

이 방법의 장점은 다음과 같습니다.또한 Equals의 모든 시나리오도 항상 커버하고 있습니다.

메모: key1과 key2는 불변이어야 합니다.그래야 안정적인 키 개체를 구성할 수 있습니다.

여러 키 또는 값을 전달하도록 클래스를 만들 수 있으며 이 클래스의 오브젝트를 맵의 파라미터로 사용할 수 있습니다.

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

        }

    }

    }

 }

다음 링크에서 다운로드 할 수 있습니다.https://github.com/VVS279/DoubleKeyHashMap/blob/master/src/com/virtualMark/doubleKeyHashMap/DoubleKeyHashMap.java

https://github.com/VVS279/DoubleKeyHashMap

value 해시맵, value 해시맵,

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

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

org.apache.commons.lang3을 사용합니다.태플. 페어는 매우 쉽다.

   Map<String, Pair<String, Integer>> map= new HashMap<>(); 
   map.put("key", Pair.of("a", 1)); 
   int value = map.get("key").getRight();
   

언급URL : https://stackoverflow.com/questions/14677993/how-to-create-a-hashmap-with-two-keys-key-pair-value

반응형