Podoba mi się, w jaki sposób Java ma mapę, w której można na przykład definiować typy każdego wpisu na mapie <String, Integer>
.
To, czego szukam, to rodzaj kolekcji, w której każdy element w kolekcji jest parą wartości. Każda wartość w parze może mieć swój własny typ (jak powyższy przykład Ciąg i Liczba całkowita), który jest definiowany w czasie deklaracji.
Kolekcja zachowa podaną kolejność i nie będzie traktować jednej z wartości jako unikalnego klucza (jak na mapie).
Zasadniczo chcę być w stanie zdefiniować tablicę typu <String,Integer>
lub dowolne inne 2 typy.
Zdaję sobie sprawę, że mogę stworzyć klasę, w której są tylko 2 zmienne, ale wydaje się to zbyt szczegółowe.
Zdaję sobie również sprawę, że mógłbym użyć tablicy 2D, ale z powodu różnych typów, których muszę używać, musiałbym zrobić z nich tablice OBJECT, a potem musiałbym rzucać cały czas.
Muszę tylko przechowywać pary w kolekcji, więc potrzebuję tylko dwóch wartości na pozycję. Czy coś takiego istnieje bez wybrania się na trasę klasową? Dzięki!
Pair
, a ludzie w Google posunęli się do stworzenia znacznie lepszej alternatywy - Auto / Value . Pozwala łatwo tworzyć dobrze typowane klasy typów wartości, z odpowiednią semantyką equals / hashCode. Nigdy więcej nie będziesz potrzebowaćPair
typu!Odpowiedzi:
Klasa Pair jest jednym z tych ogólnych przykładów, które można łatwo napisać samodzielnie. Na przykład z czubka głowy:
I tak, istnieje to w wielu miejscach w sieci, z różnym stopniem kompletności i funkcjonalności. (Mój przykład powyżej ma być niezmienny).
źródło
long l = left.hashCode() * 2654435761L;
return (int)l + (int)(l >>> 32) + right.hashCode();
AbstractMap.SimpleEntry
Łatwo tego szukasz:
Jak możesz to wypełnić?
Upraszcza to:
I za pomocą
createEntry
metody może dodatkowo zmniejszyć gadatliwość w celu:Ponieważ
ArrayList
nie jest ostateczny, można go podklasować, aby ujawnićof
metodę (i wyżej wspomnianącreateEntry
metodę), co daje zwięzłą składnię:źródło
SimpleEntry
że istniejesetValue
metoda pomijania klasy rodzeństwa , która jest niezmienna. Tak więc nazwaSimpleImmutableEntry
.Entry
ma być parą klucz-wartość i jest w porządku. Ale ma słabości jako prawdziwa krotka. Na przykładhashcode
implementacjaSimpleEntry
tylko xors kodów elementów, więc<a,b>
hash do tej samej wartości co<b,a>
. Implementacje krotki często sortują leksykograficznie, aleSimpleEntry
nie implementująComparable
. Bądź więc ostrożny ...Java 9+
W Javie 9 możesz po prostu napisać:
Map.entry(key, value)
aby stworzyć niezmienną parę.Uwaga: ta metoda nie pozwala, aby klucze lub wartości były zerowe. Jeśli chcesz zezwolić na wartości null, na przykład, że chcesz to zmienić na:
Map.entry(key, Optional.ofNullable(value))
.Java 8+
W Javie 8 możesz użyć bardziej ogólnego przeznaczenia,
javafx.util.Pair
aby stworzyć niezmienną, szeregowalną parę. Klasa ta ma umożliwić klucze nieważne i wartości null. (W Javie 9 ta klasa jest zawarta wjavafx.base
module). EDYCJA: Od wersji Java 11 JavaFX został oddzielony od JDK, więc potrzebujesz dodatkowego artefaktu maven org.openjfx: javafx-base.Java 6+
W Javie 6 i nowszych możesz użyć bardziej szczegółowego
AbstractMap.SimpleImmutableEntry
dla niezmiennej pary lubAbstractMap.SimpleEntry
dla pary, której wartość można zmienić. Klasy te zezwalają również na klucze zerowe i wartości zerowe oraz są serializowane.Android
Jeśli piszesz dla Androida, po prostu użyj,
Pair.create(key, value)
aby stworzyć niezmienną parę.Apache Commons
Apache Commons Lang
zapewnia pomoc wPair.of(key, value)
tworzeniu niezmiennej, porównywalnej, możliwej do serializacji pary.Kolekcje Eclipse
Jeśli używasz par zawierających prymitywy, Eclipse Collections zapewnia kilka bardzo wydajnych klas par prymitywnych, które pozwolą uniknąć wszystkich nieefektywnych auto-boxowania i auto-rozpakowywania.
Na przykład, można użyć
PrimitiveTuples.pair(int, int)
, aby utworzyćIntIntPair
, lubPrimitiveTuples.pair(float, long)
stworzyćFloatLongPair
.Projekt Lombok
Korzystając z Project Lombok , możesz stworzyć niezmienną klasę par, pisząc:
Lombok wypełni w konstruktorze, pochłaniacze
equals()
,hashCode()
oraztoString()
metod dla Ciebie automatycznie w wygenerowanym kodu bajtowego. Jeśli chcesz statyczne metody fabryki zamiast konstruktora, npPair.of(k, v)
, wystarczy zmienić adnotacji do:@Value(staticConstructor = "of")
.Inaczej
Jeśli żadne z powyższych rozwiązań nie unosi twojej łodzi, możesz po prostu skopiować i wkleić następujący kod (który, w przeciwieństwie do klasy wymienionej w zaakceptowanej odpowiedzi, chroni przed wyjątkami NullPointerExceptions):
źródło
Pair
interfejs dla obiektów, które można utworzyć za pomocą wywołaniaTuples.pair(object1, object2)
. eclipse.org/collections/javadoc/9.2.0/org/eclipse/collections/…List<Pair<Integer, String> listOfTuple
. Jak korzystaćlistOfTuple.add()
? Jeśli zrobię -listOfTuple.add(Pair<someInteger, someString>);
to nie zadziała. Z góry dziękuję.Map.Entry
Te wbudowane klasy są również opcją. Oba implementują
Map.Entry
interfejs.AbstractMap.SimpleEntry
AbstractMap.SimpleImmutableEntry
źródło
Apache common lang3 ma klasę Pair i kilka innych bibliotek wymienionych w tym wątku. Jaka jest odpowiednik pary C ++ <L, R> w Javie?
Przykład spełniający wymagania z pierwotnego pytania:
źródło
Każdemu, kto tworzy dla Androida, możesz użyć android.util.Pair . :)
źródło
Co z
Pair
klasą „Apache Commons Lang 3” i względnymi podklasami?ImmutablePair
jest specyficzną podklasą, która nie pozwala na modyfikację wartości w parze, ale istnieją inne implementacje z różnymi semantycznymi. Są to współrzędne Maven, jeśli ich potrzebujesz.źródło
Możesz napisać ogólną klasę Pary <A, B> i użyć jej w tablicy lub na liście. Tak, musisz napisać klasę, ale możesz ponownie użyć tej samej klasy dla wszystkich typów, więc musisz to zrobić tylko raz.
źródło
Rozwijając inne odpowiedzi, ogólna niezmienna para powinna mieć metodę statyczną, aby uniknąć zaśmiecania kodu wywołaniem konstruktora:
jeśli nazwiesz metodę statyczną „of” lub „pairOf”, kod stanie się płynny, ponieważ możesz pisać:
szkoda, że podstawowe biblioteki java są tak rzadkie w takich rzeczach, że do robienia takich podstawowych czynności trzeba używać commons-lang lub innych stron trzecich. kolejny powód do uaktualnienia do Scala ...
źródło
Chciałem zapytać, czy nie chcesz po prostu użyć
List<Pair<T, U>>
? ale oczywiście JDK nie ma klasy Pair <>. Ale szybki Google znalazł taki na Wikipedii i na forums.sun.com . Twoje zdrowieźródło
Preferowanym rozwiązaniem, tak jak to opisałeś, jest Lista par (tj. Lista).
Aby to osiągnąć, należy utworzyć klasę pary do wykorzystania w swojej kolekcji. Jest to przydatna klasa narzędziowa do dodania do bazy kodu.
Najbliższą klasą w Sun JDK zapewniającą funkcjonalność podobną do typowej klasy Pair jest AbstractMap.SimpleEntry. Możesz użyć tej klasy zamiast tworzyć własną klasę Pair, choć musiałbyś żyć z niezręcznymi ograniczeniami i myślę, że większość ludzi skrzywiłaby się z tego powodu, ponieważ tak naprawdę nie jest to zamierzona rola SimpleEntry. Na przykład SimpleEntry nie ma metody „setKey ()” i domyślnego konstruktora, więc może się okazać, że jest zbyt ograniczająca.
Pamiętaj, że Kolekcje są zaprojektowane tak, aby zawierały elementy jednego typu. Powiązane interfejsy narzędzi, takie jak Mapa, nie są w rzeczywistości kolekcjami (tzn. Mapa nie implementuje interfejsu kolekcji). Para również nie implementuje interfejsu Collection, ale jest oczywiście użyteczną klasą do budowania większych struktur danych.
źródło
Jest to oparte na kodzie JavaHelp4u.
Mniej gadatliwy i pokazuje, jak zrobić w jednym wierszu i jak zapętlać rzeczy.
źródło
Apache Crunch ma również
Pair
klasę: http://crunch.apache.org/apidocs/0.5.0/org/apache/crunch/Pair.htmlźródło
po prostu stwórz klasę jak
następnie utwórz listę tych obiektów krotek
dzięki czemu możesz również implementować inne nowe struktury danych w ten sam sposób.
źródło
Chodzi mi o to, że chociaż nie ma
Pair
klasy w Javie, jest coś podobnego:Map.Entry
Dokumentacja Map.Entry
To jest (trochę upraszczając) co
HashMap
lub właściwie dowolneMap
sklepy.Możesz utworzyć instancję
Map
przechowującą w niej swoje wartości i uzyskać zestaw wpisów. Skończysz z tym,Set<Map.Entry<K,V>>
czego skutecznie chcesz.Więc:
źródło
Spring ma
Pair<S,T>
typ w pakiecie Data Utilsorg.springframework.data.util
źródło
Co z com.sun.tools.javac.util.Pair?
źródło
Pierwszą rzeczą, o której myślę, gdy mówię o parach klucz / wartość, jest klasa właściwości, w której można zapisywać i ładować elementy do strumienia / pliku.
źródło
W projekcie Reactor (io.projectreactor: reactor-core) istnieje zaawansowana obsługa n-Tuples:
Tam możesz dostać
t.getT1(), t.getT2(), ...
Zwłaszcza za pomocą Stream lub Flux możesz nawet zmapować elementy krotki:źródło