HashMap 및 int를 키로


104

정수를 키로, 객체를 값으로 갖는 HashMap을 구축하려고합니다.

내 구문은 다음과 같습니다.

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

그러나 반환 된 오류는 다음과 같습니다.- "int"토큰에 대한 구문 오류,이 토큰 이후에 예상되는 차원-숫자 만 저장하면되므로 차원을 추가해야하는 이유 (예 : int를 배열로 만들기)를 이해할 수 없습니다. 열쇠로.

내가 뭘 할 수 있니?

미리 감사드립니다! :)


14
HashMap원시를 처리하지 않고 객체 만 처리합니다.
Menno

관련 SO 질문 이지만 int핵심이 아닌 가치입니다.
cyroxx

5
Integer대신 사용하십시오 .
Hot Licks

int를 Integer로 자동 상자 화하거나 데이터를 문자열로 저장하는 것이 더 낫습니까?
Marcin Erbel

답변:


25

HashMap은 키에 대해 내부적으로 객체를 사용하기 때문에 기본 형식을 사용할 수 없습니다. 따라서 Object (즉, 모든 개체)에서 상속 된 개체 만 사용할 수 있습니다.

그것은 HashMap의 함수 put ()이고 보시다시피 Object for K를 사용합니다.

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

"k = e.key"라는 표현을 사용하면 명확 해집니다.

Integer 및 autoboxing과 같은 래퍼를 사용하는 것이 좋습니다.


137

Integer대신 사용하십시오 .

HashMap<Integer, MyObject> myMap = new HashMap<Integer, MyObject>();

Java는 자동으로 int기본 값을 Integer객체에 자동 상자 화 합니다.

Oracle Java 문서에서 오토 박싱 에 대해 자세히 알아보십시오 .


10
그는 또한 클래스의 이름을 안myObject
아담 겐트

@AdamGent 맞습니다. 모든 클래스 이름은 대문자로 시작해야하며 권장 코드를 수정했습니다.
gaborsch 2013

3
나는 당신이 알고 있다는 것을 압니다 :) 나는 단지 OP가 알고 / 배운다는 것을 확인하고 싶습니다. 내가 아는 한 그는 유형 매개 변수에 변수 이름을 넣을 수있었습니다.
Adam Gent

1
간단히 메모 ArrayMapSimpleArrayMap
해주세요.

42

Android 장치 용 Java를 코딩하고 여기까지 오는 모든 사용자를 위해 : SparseArray더 나은 성능을 위해 사용하십시오 .

private final SparseArray<myObject> myMap = new SparseArray<myObject>();

이것으로 Integer 대신 int를 사용할 수 있습니다.

int newPos = 3;

myMap.put(newPos, newObject);
myMap.get(newPos);

7
SparseArray는 해시 맵보다 느리지 만 메모리 효율성은 더 높습니다. 따라서 큰 데이터 세트에는 사용하지 마십시오.
TpoM6oH

SparseArray는 더 느린 반면 더 나은 성능을 위해 어떻게 사용됩니까? 어느 쪽이 내 안드로이드 게임에서 사용하는

@Snake 에서처럼 SparseArray메모리 복싱 및 unboxing int를 할당 HashMap하면 vm이 가비지 수집을 위해 실행을 더 빨리 일시 중지해야합니다. 이것은 당신이 무언가를 자주 그리고 빠르게하려고 할 때 중요합니다.
Jon

1
삽입의 복잡성 SparseArrayO (n) ( HashMaphas O (1) )입니다. 요소 수가 많을 때 중요합니다. 이러한 배열의 시작 부분에 삽입하는 것이 훨씬 느립니다.
Vladimir Petrakovich

1
@ M.kazemAkhgary 정확히는 아닙니다. 위치를 찾은 다음 모든 다음 요소를 이동하기 때문에 시작시 삽입을 위해 (아님 )을 put()취 합니다. 그 자체가 실제로는 걸리지 만, 삭제 후 요소를 통해 다음 삽입 또는 반복을 수행하려면 가비지 수집이 필요 합니다. O(n)n log ndelete()O(log n)O(n)
Vladimir Petrakovich


4

HashMap이 프리미티브를 키로 허용하지 않는 주된 이유는 HashMap 이 키 비교를 위해 equals () 메소드를 사용하고 프리미티브가 아닌 객체에서만 메소드를 호출 할 수 있도록 설계 되었기 때문 입니다.

따라서 int가 Integer로 자동 박싱되면 Hashmap은 Integer 객체에서 equals () 메서드를 호출 할 수 있습니다 .

그렇기 때문에 int 대신 Integer를 사용해야합니다. int를 키로 넣는 동안 hashmap에서 오류가 발생 함을 의미합니다 (발생한 오류의 의미를 모릅니다).

그리고 그렇게 생각한다면 프리미티브를 키로하여 Map 성능을 더 빠르게 만들 수 있습니다 . Int 유형을 키로하는 Map 구현을 포함하는 FastUtil 라이브러리 가 있습니다.

이 때문에 Hashmap 보다 훨씬 빠릅니다.


1
아니요, 기본 유형을 허용하지 않는 주된 이유는 컴파일 중에 효과적으로 변환 되는 Java의 유형 삭제 때문 입니다 . BTW, 동등성 검사 를 위해 연산자를 사용하는 IdentityHashMap 이 있지만 여전히 기본 유형을 허용하지 않습니다. Map<Integer, String>Map<Object, Object>==
Yoory N.

3

HashMap은 기본 데이터 유형을 인수로 허용하지 않습니다. 객체 만 받아 들일 수 있으므로

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

작동 안 할 것이다.

선언을 다음으로 변경해야합니다.

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

그래서 당신이 다음을 할 때도

myMap.put(2,myObject);

기본 데이터 유형은 Integer 객체에 자동 박싱됩니다.

8 (int) === boxing ===> 8 (Integer)

http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html 에서 오토 박싱에 대한 자세한 내용을 읽을 수 있습니다.



1

int를 기본 유형이 아닌 Object로 사용하십시오.

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

HashMap <Integer, MyObject>를 작성했습니다. myMap = new HashMap <Integer, MyObject> (); 그러나 표시 내 문제를 만들>와 <좋은 답변 표시
franki3xe

타이핑하는 것이 고통 스럽다는 것을 알고 있지만 즉시 당신을 구하려고 노력했습니다 -1. 나는 다른 사람들과는 달리 벌칙을 부과하기 전에 언급합니다 (나는 당신을 -1하지 않았습니다).
Adam Gent

0

사용하십시오 HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();


0

숫자 만 키로 저장하면되므로 차원을 추가해야하는 이유 (예 : int를 배열로 만들기)를 이해하지 못합니다.

배열도 객체이므로 HashMap<int[], MyObject> int 배열을 키로 사용하는 유효한 구조입니다.

컴파일러는 사용자가 원하는 것이 무엇인지, 무엇을 필요로하는지 알지 못합니다. 거의 올바른 언어 구조 만보고 완전히 정확하기 위해 누락 된 것이 무엇인지 경고합니다.


1
이것에주의하십시오. 배열의 해시 값은 그 내용과 관련이 없으므로 동일한 내용을 가진 두 배열이 다른 값으로 해시되어 매우 불량한 키가 될 수 있습니다.
john16384

0

Java에서 기본 유형보다 래퍼 의 자동 박싱 공간 을 줄이고 싶기 때문에 이러한 맵에 관심이있는 사람에게는 Eclipse 컬렉션 을 사용하는 것이 좋습니다 . Trove는 더 이상 지원되지 않으며 (어쨌든 꽤 인기가 있지만) 상당히 신뢰할 수없는 라이브러리라고 생각하며 Eclipse 컬렉션 과 비교할 수 없습니다 .

import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap;

public class Check {
    public static void main(String[] args) {
        IntObjectHashMap map = new IntObjectHashMap();

        map.put(5,"It works");
        map.put(6,"without");
        map.put(7,"boxing!");

        System.out.println(map.get(5));
        System.out.println(map.get(6));
        System.out.println(map.get(7));
    }
}

이 예제에서 IntObjectHashMap 위의 .

int-> object 매핑 이 필요 하므로 map은 본질적으로 int 유형을 인덱스로 사용하는 연관 배열 이므로 YourObjectType[]배열 사용을 고려 하거나 List<YourObjectType>인덱스로 값에 액세스하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.