Tuple (немодифицируемый упорядоченный список гетерогенных элементов) в Java
Интересно, почему Java не имеет реализации структуры данных кортежа в своей стандартной библиотеке. Например, С++ имеет очень хорошую реализацию этого набора гетерогенных значений фиксированного размера. То же самое в Haskell. В Java я знаю только javatuples и некоторую поддержку в Функциональная Java через типы Product
(P1 - P8
). Интересно, почему tuple
или по крайней мере pair
не в стандартной библиотеке вообще? Даже разработчики Android SDK добавили собственную реализацию из 2-кортежей (пары).
Ответы
Ответ 1
"Java-способ" - это определение классов, специфичных для использования, а не таких типов облегченного полукласса. Если вы думаете об этом, кортеж - это просто упрощенная структура; люди из Java предпочли бы, чтобы вы просто пошли вперед и создали структуру.
Эта перспектива немного изменилась, особенно в Java 8 с ее lambdas (что давило на JDK, чтобы предоставить общие интерфейсы типа Function
, а не интерфейсы конкретных случаев, например FooCallback
). Но это все еще довольно сильное мышление для многих разработчиков Java, и в этом есть смысл. Java - очень статически типизированный язык; кортеж находится где-то между статической типизацией и динамической типизацией, поскольку в системе типов нет ничего, что помешало бы вам думать об этом (int, String)
, который представляет собой идентификатор клиента, а на самом деле это (int, String)
, представляющий идентификатор заказа и его описание.
См., например, эту дискуссию по проблеме в рамках проекта Guava. Конечно, это не официальное; но это хорошее представление о мышлении Java.
Ответ 2
Существует хорошая библиотека под названием javatuples
. Он определяет общие типы кортежей для arities от 1 (Unit
) до 10 (Decade
) и всех основных методов, таких как equals
, hashCode
, toString
и даже compareTo
.
Официальный сайт: http://www.javatuples.org/
Зависимость от Maven:
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>[version]</version>
<scope>compile</scope>
</dependency>
(на данный момент последняя версия 1.2
)
Ответ 3
Он имеет:
Collections.unmodifiableList(yourList)
сделает трюк.
Я думаю, что универсальность JCF делает ненужным существование явных кортежей.
Я предполагаю, что по кортежу вы имеете в виду упорядоченный неизменный список элементов (согласно определение википедии).
Что касается сторонней библиотеки, то мой поиск мощности в google дал this, это и, конечно, this.
Ответ 4
Мы с коллегой обсуждали это несколько недель назад. Единственное решение, которое я мог придумать, заключалось в том, чтобы внутренне хранить значения в Map<Class, Object>
и иметь некоторый метод доступа getValue(Class)
. В противном случае, как вы получаете доступ к значениям в кортеже? Вы не можете иметь общий класс Tuple
с методами для каждого члена, например. getInteger
, getString
и т.д., потому что эти методы не будут известны до выполнения, когда вы создадите кортеж. Это также означает, что у вас никогда не было бы двух членов с одним типом - как бы вы могли написать такой класс, чтобы во время выполнения он знал, какой объект получить?
Ответ 5
FunctionalJava предоставил набор классов P
(Product), которые, как мне кажется, соответствуют этой идее. Он предоставляет P1
- P8
, чтобы разрешить до 8 элементов Tuples. Я согласен с объяснением Гуавы, почему они обескуражены, но там вы идете.
FunctionalJava-P
Ответ 6
В среде выполнения Java есть тип, и он называется Entry. Это интерфейс внутри карты, и в AbstractMap есть простая реализация.
http://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html
http://docs.oracle.com/javase/7/docs/api/java/util/AbstractMap.SimpleEntry.html
Вы можете использовать его как кортеж для двух участников, вы можете даже применить дженерики. Я подумал бы, что я сделал неправильно, если мне понадобилось больше элементов, чем два. Вероятно, стоит того же класса.