Java - Yeni Giriş nasıl oluşturulur (anahtar, değer)


291

Ben benzer yeni öğe oluşturmak istiyorum Util.Map.Entrybu yapıyı içerecek key, value.

Sorun şu ki, Map.Entrybir arabirim oluşturduğum için bir örnek oluşturamıyorum.

Map.Entry için nasıl yeni bir genel anahtar / değer nesnesi oluşturmayı bilen var mı?

Yanıtlar:


79

Map.Entry<K, V>Arayüzü kendiniz uygulayabilirsiniz :

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

Ve sonra kullanın:

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

117
Tabii ki - bunun için hazır bir çözüm olup olmadığını merak ettim. Kodumu olabildiğince standart yapmaya çalışıyorum ...
Spiderman

1
Harita uygulamasının bazı uygulamalarının neden son olarak anahtar olduğunu açıklayabilir misiniz (HashMap, ConcurrentHashMap gibi), ancak TreeMap, WeakHashMap gibi diğer uygulamalarda değil?
AKS

7
Map.ntry
John Tang Boyland

Java 7 Güncelleme 80'den itibaren yukarıda uyguladım ve çalıştı ( pastebin ). Başka hiçbir yöntem geçersiz kılınmadı.
gümüş

807

Var public static class AbstractMap.SimpleEntry<K,V>. Abstractİsmin bir kısmının sizi yanlış yönlendirmesine izin vermeyin : aslında bir sınıf DEĞİLDİRabstract (ancak üst seviyesi AbstractMap).

Bir olmasına ne demeli statico iç içe sınıf araçlar YAPMAYIN kapatıcı bir ihtiyaç AbstractMap, bunu oluşturmaya örneği bu derler cezası gibi bir şey bu yüzden:

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

Başka bir cevapta belirtildiği gibi, Guava'nın da kullanabileceğiniz uygun bir staticfabrika yöntemi Maps.immutableEntryvardır.


Dedin:

Map.EntryKendini kullanamıyorum çünkü görünüşe göre yeni başlatamadığım salt okunur bir nesneinstanceof

Bu tamamen doğru değil. Doğrudan (yani ile new) başlatamamanızın nedeni , bir interface Map.Entry.


Uyarı ve ipucu

Belgelerinde belirtildiği gibi, AbstractMap.SimpleEntryolduğu @since 1.6sen 5.0 yapışmış eğer öyleyse, o zaman sizin için kullanılabilir değil.

Bilinen başka bir sınıfı aramak için implements Map.Entry, aslında doğrudan javadoc'a gidebilirsiniz. Gönderen Java 6 sürümü

Arayüz Haritası.

Bilinen Tüm Uygulama Sınıfları :

Ne yazık ki 1.5 sürümü , kullanabileceğiniz bilinen herhangi bir uygulama sınıfını listelemiyor, bu nedenle kendi uygulamanızı uygulamakta sıkışmış olabilirsiniz.


Yukarıdaki satır benim için derleme hatası döndürüyor (java 5, BTW kullanıyorum) - hata mesajı: 'AbstractMap.SimpleEntry türü görünmüyor'
Spiderman

6
Bunun nedeni AbstractMap.SimpleEntry, belgelerde görebileceğiniz gibi Java 6'ya kadar herkese açık değildi.
Jesper

Tamam, bu yüzden kısa tartışmayı özetlemek için - Java 5'de kullanıma hazır bir çözüm yok - kendi uygulamamı kullanmalıyım.
Spiderman

4
İşaret etmek için +1 AbstractMap.SimpleEntry. Sanırım her gün yeni bir şeyler öğreniyorsun!
Priidu Neemre

"ekli bir AbstractMap örneği" içine alarak ne demek istiyorsun. Çevreleme, java'da teknik bir terim veya başka bir şey mi çıkardı? Lütfen bana yol göster.
C grafikleri

70

Java 9'dan başlayarak, değişmez bir giriş oluşturmaya izin veren yeni bir yardımcı program yöntemi vardır Map#entry(Object, Object).

İşte basit bir örnek:

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

Değişmez olduğu için, çağrı setValuebir UnsupportedOperationException. Diğer sınırlamalar, serileştirilememesidir ve nullanahtar veya değer yasak olduğu için, sizin için kabul edilebilir değilse, AbstractMap.SimpleImmutableEntryveya kullanmanız gerekecektir AbstractMap.SimpleEntry.

Not: İhtiyacınız Map0 ila en fazla 10 (anahtar, değer) çiftiyle doğrudan a oluşturmaksa , bunun yerine yazım yöntemlerini kullanabilirsiniz Map.of(K key1, V value1, ...).



34

AbstractMap.SimpleEntry örneği:

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

Örneklendirmek:

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

Satır ekle:

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

Satırları getir:

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

Yazdırmalı:

2
3
20
30
2
4

Grafik yapılarının kenarlarını tanımlamak için iyidir. Kafandaki nöronlar arasındaki gibi.


18

Aslında ile gidebilirsiniz: Map.Entry<String, String> en= Maps.immutableEntry(key, value);


Yararlı. github.com/google/guava Guava, Google'dan yeni koleksiyon türleri (multimap ve multiset gibi), değişmez koleksiyonlar, bir grafik kütüphanesi ve eşzamanlılık, G / Ç, karma, önbellekleme, ilkel, ip ve daha fazlası! Google içindeki çoğu Java projesinde yaygın olarak kullanılmaktadır ve diğer birçok şirket tarafından da yaygın olarak kullanılmaktadır.
Languoguang

13

Neden Map.Entry? Sanırım anahtar / değer çifti gibi bir durum dava için uygun.

java.util.AbstractMap.SimpleImmutableEntryVeya kullanınjava.util.AbstractMap.SimpleEntry


6

org.apache.commons.lang3.tuple.Pairuygular java.util.Map.Entryve bağımsız olarak da kullanılabilir.

Ayrıca diğerleri gibi Guava'nın com.google.common.collect.Maps.immutableEntry(K, V)hile yapar.

PairAkıcı Pair.of(L, R)sözdizimini tercih ederim .


2
ImmutablePairBunun yerine önerebilir miyim ?
beluchin

Gerçekten org.apache.commons.lang3.tuple.Pair sınıfını seviyorum, harika!
Laurens Op 't Zandt

Bu konuda sevmediğim tek şey, sola = sağa ve anahtar = değere sol, sağ, anahtar, değere serileştirilmesidir. Serileştirilmiş dizede sadece 2 ekstra yararsız (belki) değer.
Vikrant Goel

4

Her zaman kullandığım genel bir Pair sınıfı tanımladım. Bu harika. Bonus olarak, statik bir fabrika yöntemi (Pair.create) tanımlayarak yalnızca tür argümanlarını yarı sık yazmak zorunda kalıyorum.

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
Üzgünüm, diğer tüm yorumları okumadan önce bunu yayınladım. Standart lib dahil bir şey istiyor gibi görünüyor ...
Nels Beckman

2
Google Guava, Pairuygulamaların neden kötü bir şey olduğunu iyi bir şekilde belirtiyor . Kaynak
Ingo Bürk

3

Clojure kullanıyorsanız başka bir seçeneğiniz vardır:

(defn map-entry
  [k v]
  (clojure.lang.MapEntry/create k v))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.