Mógłby mi ktoś wyjaśnić fenomen struktury Tuple? Po co została stworzona i dlaczego może pomieścić tylko 8elementów? Jakie ma zastosowanie? Jakiś sensowny przykład? Uczę się biblioteki vavr ale nie widzę sensu w zastosowaniu Tuple.
W tuplach można zapisać osobę (imię, nazwisko, ...), współrzędne (x, y, z), i inne powiązane informacje np. (nazwa_pliku, rozmiar, data_utworzenia). Użyteczna rzecz.
8 elementów jest zahardkodowane https://github.com/vavr-io/vavr/blob/master/vavr/src-gen/main/java/io/vavr/Tuple.java ale nie wiem, czy stoi za tym jakiś głębszy powód. Poza tym myślę, że jeżeli potrzebna jest większa liczba elementów, to może lepiej stworzyć klasę.
Krotka składa się z określonej liczby pól, a więc umożliwia zarządzanie wieloma wartościami naraz. Podobną rolę spełniają klasy bez logiki. Przy użyciu krotek nie trzeba jednak tworzyć nowej klasy. Dla przykładu:
class Human {
final String firstName;
final String lastName
final int age;
// itd
public Human(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
// opcjonalnie można dodać gettery jak ktoś lubi
}
Jeśli użyjemy krotki np Tuple3<String, String, Integer>
to nie musimy tworzyć tej klasy, a więc jest mniej kodu. To jest główna zaleta krotek. Wadą krotek jest oczywiście to, że krotka jest czymś totalnie ogólnym i nie niesie informacji o zawartości. Konkretnie to nazwa klasy Tuple3 nie niesie takiej informacji jak Human, a nazwa pola Tuple3._1 nie niesie takiej informacji jak Human.firstName.
Krotek należy używać wtedy, gdy tworzenie klasy z konkretnymi nazwami daje zbyt mało korzyści, by uzasadnić tworzenie nowej klasy. Dla przykładu jeśli chcemy zwrócić dwie wartości z metody, a obie mają konkretne typy (np OutputStream + Charset) to tworzenie klasy np o nazwie OutputStreamWithCharset jest bez sensu jeśli możemy po prostu użyć krotki Tuple2<OutputStream, Charset>
. Ciężko dać ogólną zasadę kiedy używać krotek - z czasem sam nabędziesz intuicji kiedy warto tworzyć nową klasę, a kiedy można pozostać przy krotce. Jednym z momentów kiedy warto zmienić krotkę na klasę jest np wtedy, gdy widzisz coś typu tuple._1
i musisz się dłuższą chwilę zastanawiać o co biega. Wtedy stworzenie nowej klasy z konkretnymi nazwami pozwoli na zwiększenie czytelności kodu.
dlaczego może pomieścić tylko 8elementów
Gdzieś trzeba postawić limit, bo wraz ze zwiększaniem ilości dostępnych wariantów krotek szybko puchnie kod biblioteki (tutaj: biblioteki vavr). 8 to pewien kompromis. W Scali takim kompromisem jest 22, a i tak ludzie narzekają.
Poza tym krotki zawsze możesz zagnieżdżać jeśli już bardzo chcesz przerzucać skomplikowane, a nieponazywane struktury danych. Czyli np mieć instancję typu: Tuple8<Tuple8<....>, Tuple6<...>, String, Integer, ...>
itd Takie coś jednak w Javie będzie obsługiwać się mocno niewygodnie i lepiej stworzyć klasę dla tak dużej ilości parametrów. Albo nawet (lepiej) kilka klas i użyć kompozycji.