이름 + 번호에 바인드 된 값을 저장하고 싶습니다. Like (John, 1) (RED) and (John, 2) (BLUE) 및 (Elize, 1) (GREEN) 고유 한 결합 된 2 개의 키를 어떻게 저장할 수 있습니까?HashMap에 두 개의 결합 된 고유 키를 저장 하시겠습니까?
답변
복합 키 (여기서 이름과 번호)를 나타내는 새로운 유형을 만듭니다. hashCode()
및 equals()
을 재정의해야 할 것이므로 유형을 변경 불가능하게 만들 것을 강력히 권합니다. 예를 들어 :
public final class NameIntPair {
private final int intValue;
private final String name;
public NameIntPair(int intValue, String name) {
this.intValue = intValue;
this.name = name;
}
@Override
public int hashCode() {
int hash = 17;
hash = hash * 31 + intValue;
hash = hash * 31 + (name == null ? 0 : name.hashCode());
return hash;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NameIntPair)) {
return false;
}
if (this == obj) {
return true;
}
NameIntPair other = (NameIntPair) obj;
return other.intValue == intValue && Objects.equal(other.name, name);
}
}
내가 여기에 명시 적으로 무효 검사를 피하기 위해 편의를 위해 구아바에서 Objects.equal
을 사용하고 있습니다 - 당신은 구아바를 사용하지 않을 경우, 당신은 동등한를 사용하거나 코드에서 무효 처리해야 할 것 중 하나. 또는 null 이름을 방지하고 생성자에서 유효성을 검사 할 수 있습니다.
는 다음과 같이 특정 키 클래스를 정의 :
public class Key {
final String name;
final int number;
public Key(String name, int number) {
this.name = name;
this.number = number;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result
+ ((name == null) ? 0 : name.hashCode());
result = prime * result + number;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Key other = (Key) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (number != other.number)
return false;
return true;
}
private Test getOuterType() {
return Test.this;
}
}
중요한 점은 당신이 의도 한대로 작동하도록 수집을 가능하게 등호와 hashCode의 계약 (키를 사용하여 표준 모음)을 존중하도록하는 것입니다.
여기 Eclipse로 생성 된 생성 된 메소드를 사용했지만이 주제에 대해 도움이되는 많은 동적 유틸리티 (예 : 구아바)도 있습니다.
조합의 고유성에 대해 확신 할 수 있고 키 객체가 쉽게 문자열을 지정할 수 있다면 문자열 연결을 사용합니다. 특수 문자를 사용하여 키를 결합 할 수 있습니다 (예 : "John # 1"및 "John # 2"). 나는 그것에 대해 확신하지 않으면
나는 Guava's Table 사용합니다 :
일반적으로, 당신이 한 번에 두 개 이상의 키에 인덱스하려고 할 때, 당신은지도처럼 뭔가 바람 것 (이름, 지도 (성, 사람)), 사용하기에는 추악하고 어색합니다. 구아바 어떤 "행"형과 "열"타입이 사용 사례 을 지원하는 새로운 콜렉션 유형 테이블을 제공
그래서 표
순서쌍 연관 집합이다 행 키 및 열 키라는 단일 키 값이 있습니다.
이 경우에 적합한 연결된 키를 사용하여 간단한 다른 방법도 있습니다 : 이름이 너무 오래하지 않은 경우
가public static String getKey(String name, int number) {
return name + number;
}
, 문자열 연결에 대한 오버 헤드가 복합 키 객체를 생성하기위한 제안보다 더 큰되지 않습니다는 다른 답은.
감사합니다.하지만 HashMap에서 hashcode/equals로 작업 한 적이 없지만, John, 1의 가치를 얻을 수있는 방법을 보여줄 수 있습니까? – user1621988