Java-새 항목을 작성하는 방법 (키, 값)


291

나는 유사에 새 항목을 만들고 싶습니다 Util.Map.Entry그 구조를 포함됩니다 key, value.

문제는 Map.Entry인터페이스이기 때문에 인스턴스화 할 수 없다는 것입니다.

누구나 Map.Entry에 대한 새로운 일반 키 / 값 객체를 만드는 방법을 알고 있습니까?

답변:


79

Map.Entry<K, V>인터페이스를 직접 구현할 수 있습니다 .

import java.util.Map;

final class MyEntry<K, V> implements Map.Entry<K, V> {
    private final K key;
    private V value;

    public MyEntry(K key, V value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public K getKey() {
        return key;
    }

    @Override
    public V getValue() {
        return value;
    }

    @Override
    public V setValue(V value) {
        V old = this.value;
        this.value = value;
        return old;
    }
}

그런 다음 사용하십시오.

Map.Entry<String, Object> entry = new MyEntry<String, Object>("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());

117
물론-즉시 사용 가능한 솔루션이 없는지 궁금했습니다. 가능한 한 표준 코드를 만들려고 노력하고 있습니다 ...
Spiderman

1
Map의 일부 구현이 HashMap, ConcurrentHashMap과 같이 최종 키가 왜 중요한지 설명하지만 TreeMap, WeakHashMap과 같은 다른 구현에서는 그렇지 않은 이유를 설명해 주시겠습니까?
AKS

7
주어진 코드는 인터페이스 Map.Entry에 의해 요구되는 equals와 hashCode도 무시하지 않기 때문에 완전히 정확하지 않습니다.
John Tang Boyland

Java 7 Update 80부터 위에서 구현했으며 작동했습니다 ( pastebin ). 다른 방법은 재정의되지 않았습니다.
실버

806

있습니다 public static class AbstractMap.SimpleEntry<K,V>. 송출하지 마십시오 Abstract는 사실이다 : 이름의 일부가 당신을 오해 하지abstract 클래스 (그러나 최상위AbstractMap 이다).

static중첩 된 클래스 라는 사실은 인스턴스화를 위해 엔 클로징 인스턴스가 필요 하지AbstractMap 않으므로 다음과 같이 컴파일됩니다.

Map.Entry<String,Integer> entry =
    new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);

다른 답변에서 언급했듯이 구아바에는 편리한 static공장 방법 Maps.immutableEntry이 있습니다.


당신은 말했다 :

Map.Entry분명히 인스턴스화 할 수없는 읽기 전용 객체이기 때문에 자체적으로 사용할 수 없습니다.instanceof

완전히 정확하지는 않습니다. 직접 인스턴스화 할 수없는 이유는 (예 :) new때문 interface Map.Entry입니다.


경고와 팁

설명서에서 언급했듯이 AbstractMap.SimpleEntryis @since 1.6이므로 5.0을 고수하면 사용할 수 없습니다.

알려진 다른 클래스를 찾으려면 implements Map.Entry실제로 javadoc으로 직접 이동할 수 있습니다. 에서 자바 6 버전

인터페이스 Map.Entry

알려진 모든 구현 클래스 :

불행히도 1.5 버전 에는 사용할 수있는 알려진 구현 클래스가 나열되어 있지 않으므로 자신의 구현을 고수했을 수도 있습니다.


나를 위해 위의 라인을 반환 컴파일 오류 (내가 BTW, 자바 5를 사용하고 있습니다) - 오류 메시지는 다음과 같습니다 '타입 AbstractMap.SimpleEntry이 표시되지 않습니다'
스파이더 맨

6
AbstractMap.SimpleEntry문서에서 볼 수 있듯이 Java 6까지 공개되지 않았기 때문 입니다.
Jesper

자, 짧은 논의를 요약하면 Java 5에는 기본 솔루션이 없습니다. 자신의 구현을 사용해야합니다.
스파이더 맨

4
지적 +1 AbstractMap.SimpleEntry. 매일 새로운 것을 배우는 것 같아요!
Priidu Neemre

"Enclosing AbstractMap instance"로 묶는 것은 무엇을 의미합니까? Enclosing은 Java에서 기술적 용어 또는 무언가를 유추합니까? 안내해주세요.
C graphics

70

Java 9 부터는 불변 항목을 작성할 수있는 새로운 유틸리티 메소드가 Map#entry(Object, Object)있습니다.

다음은 간단한 예입니다.

Entry<String, String> entry = Map.entry("foo", "bar");

불변이므로 호출 setValue하면가 발생합니다 UnsupportedOperationException. 다른 제한 사항은 직렬화 할 수 없으며 null키 또는 값이 금지되어 있기 때문에 허용되지 않는 경우 AbstractMap.SimpleImmutableEntry또는 AbstractMap.SimpleEntry대신 사용해야 합니다.

NB :Map 0에서 최대 10 (키, 값) 쌍으로 직접을 작성해야하는 경우 type 유형의 메소드를 대신 사용할 수 있습니다 Map.of(K key1, V value1, ...).



34

AbstractMap.SimpleEntry의 예 :

import java.util.Map; 
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;

인스턴스화 :

ArrayList<Map.Entry<Integer, Integer>> arr = 
    new ArrayList<Map.Entry<Integer, Integer>>();

행 추가 :

arr.add(new AbstractMap.SimpleEntry(2, 3));
arr.add(new AbstractMap.SimpleEntry(20, 30));
arr.add(new AbstractMap.SimpleEntry(2, 4));

행 가져 오기 :

System.out.println(arr.get(0).getKey());
System.out.println(arr.get(0).getValue());
System.out.println(arr.get(1).getKey());
System.out.println(arr.get(1).getValue());
System.out.println(arr.get(2).getKey());
System.out.println(arr.get(2).getValue());

인쇄해야합니다 :

2
3
20
30
2
4

그래프 구조의 가장자리를 정의하는 데 좋습니다. 당신의 머리에있는 뉴런 사이의 것과 같습니다.


18

실제로 다음을 수행 할 수 있습니다. Map.Entry<String, String> en= Maps.immutableEntry(key, value);


유용합니다. github.com/google/guava Guava는 Google의 핵심 자바 라이브러리 모음으로, 새로운 컬렉션 유형 (예 : 멀티 맵 및 멀티 세트), 변경 불가능한 컬렉션, 그래프 라이브러리 및 동시성, I / O, 해싱, 캐싱, 기본 요소, 문자열 등! Google의 대부분의 Java 프로젝트에서 널리 사용되며 다른 많은 회사에서도 널리 사용됩니다.
Languoguang

13

Map.Entry? 키-값 쌍과 같은 것이이 경우에 적합하다고 생각합니다.

사용 java.util.AbstractMap.SimpleImmutableEntry또는java.util.AbstractMap.SimpleEntry


6

org.apache.commons.lang3.tuple.Pair 구현하다 java.util.Map.Entry 하고 독립형으로 사용할 수도 있습니다.

또한 다른 사람들이 언급 한 것처럼 구아바의 com.google.common.collect.Maps.immutableEntry(K, V)트릭을 수행합니다.

나는 Pair유창한 Pair.of(L, R)구문을 선호 합니다.


2
ImmutablePair대신 제안해도 될까요?
beluchin

나는 org.apache.commons.lang3.tuple.Pair 클래스를 정말 좋아합니다.
Laurens Op 't Zandt

내가 싫어하는 유일한 것은 왼쪽, 오른쪽, 키, 왼쪽 = 키 및 오른쪽 = 값으로 직렬화된다는 것입니다. 직렬화 된 문자열에 2 개의 여분의 쓸모없는 (아마도) 값이 있습니다.
Vikrant Goel

4

항상 사용하는 일반 쌍 클래스를 정의했습니다. 훌륭합니다. 보너스로 정적 팩토리 메소드 (Pair.create)를 정의하면 유형 인수를 자주 절반 만 작성하면됩니다.

public class Pair<A, B> {

    private A component1;
    private B component2;

    public Pair() {
            super();
    }

    public Pair(A component1, B component2) {
            this.component1 = component1;
            this.component2 = component2;
    }

    public A fst() {
            return component1;
    }

    public void setComponent1(A component1) {
            this.component1 = component1;
    }

    public B snd() {
            return component2;
    }

    public void setComponent2(B component2) {
            this.component2 = component2;
    }

    @Override
    public String toString() {
            return "<" + component1 + "," + component2 + ">";
    }

    @Override
    public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result
                            + ((component1 == null) ? 0 : component1.hashCode());
            result = prime * result
                            + ((component2 == null) ? 0 : component2.hashCode());
            return result;
    }

    @Override
    public boolean equals(Object obj) {
            if (this == obj)
                    return true;
            if (obj == null)
                    return false;
            if (getClass() != obj.getClass())
                    return false;
            final Pair<?, ?> other = (Pair<?, ?>) obj;
            if (component1 == null) {
                    if (other.component1 != null)
                            return false;
            } else if (!component1.equals(other.component1))
                    return false;
            if (component2 == null) {
                    if (other.component2 != null)
                            return false;
            } else if (!component2.equals(other.component2))
                    return false;
            return true;
    }

    public static <A, B> Pair<A, B> create(A component1, B component2) {
            return new Pair<A, B>(component1, component2);
    }

}

1
죄송합니다. 다른 모든 의견을 읽기 전에 게시했습니다. 표준 라이브러리에 포함 된 것을 원하시는 것 같습니다.
Nels Beckman

2
Google Guava는 Pair구현이 나쁜 이유를 잘 지적 합니다. 출처
Ingo Bürk

3

Clojure를 사용하는 경우 다른 옵션이 있습니다.

(defn map-entry
  [k v]
  (clojure.lang.MapEntry/create k v))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.