AKTUALIZACJA: Ta odpowiedź jest odpowiedzią na pierwotne pytanie: Czy Java SE 8 ma pary czy krotki? (I domyślnie, jeśli nie, dlaczego nie?) OP zaktualizował pytanie bardziej kompletnym przykładem, ale wydaje się, że można je rozwiązać bez użycia jakiejkolwiek struktury par. [Uwaga od OP: oto inna poprawna odpowiedź .]
Krótka odpowiedź brzmi: nie. Musisz albo stworzyć własną, albo wprowadzić jedną z kilku bibliotek, które ją implementują.
Posiadanie Pair
zajęć z Java SE zostało zaproponowane i odrzucone przynajmniej raz. Zobacz ten wątek dyskusyjny na jednej z list mailingowych OpenJDK. Kompromisy nie są oczywiste. Z jednej strony istnieje wiele implementacji Par w innych bibliotekach i kodzie aplikacji. To pokazuje potrzebę, a dodanie takiej klasy do Java SE zwiększy ponowne użycie i udostępnianie. Z drugiej strony posiadanie klasy Pair zwiększa pokusę tworzenia skomplikowanych struktur danych z par i kolekcji bez tworzenia niezbędnych typów i abstrakcji. (To parafraza przesłania Kevina Bourilliona z tego wątku.)
Polecam wszystkim przeczytanie tego całego wątku e-mail. Jest niezwykle wnikliwy i nie ma ognia. To całkiem przekonujące. Kiedy się zaczęło, pomyślałem: „Tak, powinna być klasa Pair w Java SE”, ale zanim wątek dobiegł końca, zmieniłem zdanie.
Należy jednak pamiętać, że JavaFX ma klasę javafx.util.Pair . Interfejsy API JavaFX ewoluowały niezależnie od interfejsów API Java SE.
Jak widać z połączonego pytania Co jest równoważne parze C ++ w Javie? wokół dość podobnego API jest dość duża przestrzeń projektowa. Czy obiekty powinny być niezmienne? Czy powinny być możliwe do serializacji? Czy powinny być porównywalne? Czy klasa powinna być ostateczna, czy nie? Czy należy zamówić dwa elementy? Czy powinien to być interfejs czy klasa? Po co zatrzymywać się w parach? Dlaczego nie trzy, czterokąty lub N-krotki?
I oczywiście istnieje nieunikniona nazwa dla elementów:
- (a, b)
- (pierwsza sekunda)
- (Lewo prawo)
- (samochód, cdr)
- (foo, bar)
- itp.
Jednym wielkim problemem, o którym prawie nie wspomniano, jest związek par z prymitywami. Jeśli masz układ (int x, int y)
odniesienia reprezentujący punkt w przestrzeni 2D, reprezentowanie go jako Pair<Integer, Integer>
pochłania trzy obiekty zamiast dwóch 32-bitowych słów. Co więcej, obiekty te muszą znajdować się na stercie i będą obciążone GC.
Wydaje się jasne, że podobnie jak w przypadku strumieni, niezbędne byłoby istnienie prymitywnych specjalizacji dla par. Czy chcemy zobaczyć:
Pair
ObjIntPair
ObjLongPair
ObjDoublePair
IntObjPair
IntIntPair
IntLongPair
IntDoublePair
LongObjPair
LongIntPair
LongLongPair
LongDoublePair
DoubleObjPair
DoubleIntPair
DoubleLongPair
DoubleDoublePair
Nawet i IntIntPair
nadal wymagałoby jednego obiektu na stercie.
Przypominają one oczywiście rozpowszechnianie się funkcjonalnych interfejsów w java.util.function
pakiecie w Javie SE 8. Jeśli nie chcesz rozdętego API, które byś pominął? Można również argumentować, że to nie wystarczy i że Boolean
należy dodać także specjalizacje, powiedzmy, do .
Mam wrażenie, że gdyby Java dodała klasę Pair już dawno temu, byłoby to proste, a nawet uproszczone i nie spełniłoby wielu przypadków użycia, które teraz przewidujemy. Weź pod uwagę, że gdyby Para została dodana w ramach czasowych JDK 1.0, prawdopodobnie byłaby zmienna! (Spójrz na java.util.Date.) Czy ludzie byliby z tego zadowoleni? Domyślam się, że gdyby w Javie istniała klasa Pair, byłaby to trochę nieprzydatna i wszyscy nadal będą się rozwijać, aby zaspokoić swoje potrzeby, w bibliotekach zewnętrznych będą różne implementacje Pair i Tuple, a ludzie nadal będą się kłócić / dyskutować o tym, jak naprawić klasę Java pary. Innymi słowy, jakby w tym samym miejscu, w którym jesteśmy dzisiaj.
Tymczasem trwają prace nad fundamentalnym problemem, którym jest lepsza obsługa JVM (i ostatecznie języka Java) dla typów wartości . Zobacz ten dokument Stan wartości . Jest to wstępna, spekulacyjna praca, która obejmuje tylko kwestie z perspektywy JVM, ale ma już za sobą wiele przemyśleń. Oczywiście nie ma gwarancji, że wejdzie to w Javę 9 lub kiedykolwiek wejdzie gdziekolwiek, ale pokazuje aktualny kierunek myślenia na ten temat.
AbstractMap.SimpleImmutableEntry<K,V>
od lat ... Ale w każdym razie, zamiast mapowaniai
do(i, value[i])
tylko do filtrowania przezvalue[i]
i mapowanie z powrotemi
: dlaczego nie tylko przez filtrvalue[i]
w pierwszej kolejności, bez mapowania?