Использование пар или 2-кортежей в Java [дубликат]
этот вопрос уже есть ответ здесь:
коллекция Java пар значений? (кортежи?)
17 ответов
моя хэш-таблица в Java выиграет от значения, имеющего структуру кортежа. Какие структуры данных я могу использовать в Java для этого?
Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ...
14 ответов:
Я не думаю, что в Java есть класс кортежа общего назначения, но пользовательский может быть таким же простым, как и следующий:
public class Tuple<X, Y> { public final X x; public final Y y; public Tuple(X x, Y y) { this.x = x; this.y = y; } }конечно, есть некоторые важные последствия того, как проектировать этот класс дальше в отношении равенства, неизменности и т. д., особенно если вы планируете использовать экземпляры в качестве ключей для хэширования.
javatuples - это выделенный проект для кортежей на Java.
Unit<A> (1 element) Pair<A,B> (2 elements) Triplet<A,B,C> (3 elements)
Apache Commons при условии, некоторые общие утилиты java, включая пара. Он реализует
Map.Entry,ComparableиSerializable.
в качестве расширения к @ maerics хороший ответ, я добавил несколько полезных методов:
public class Tuple<X, Y> { public final X x; public final Y y; public Tuple(X x, Y y) { this.x = x; this.y = y; } @Override public String toString() { return "(" + x + "," + y + ")"; } @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof Tuple)){ return false; } Tuple<X,Y> other_ = (Tuple<X,Y>) other; // this may cause NPE if nulls are valid values for x or y. The logic may be improved to handle nulls properly, if needed. return other_.x.equals(this.x) && other_.y.equals(this.y); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((x == null) ? 0 : x.hashCode()); result = prime * result + ((y == null) ? 0 : y.hashCode()); return result; } }
еще 2 цента: начиная с Java 7, теперь есть класс для этого в стандартном Lib: javafx.утиль.Пара.
и да, это стандартная Java, теперь, когда JavaFx включен в JDK:)
вот этот точно такой же вопрос в другом месте, который включает в себя более надежный
equals,hashчто maerics намекает на:эта дискуссия продолжает отражать подходы maerics vs ColinD: "должен ли я повторно использовать Кортеж класса с неспецифическим именем или создавать новый класс с конкретными именами каждый раз, когда я сталкиваюсь с этой ситуацией". Много лет назад я был в последнем лагере; я превратился в поддержку первого.
этот объект обеспечивает разумную реализацию equals (), возвращая true, если equals () истинно для каждого из содержащихся объектов.
создайте класс, который описывает концепцию, которую вы на самом деле моделируете, и используйте ее. Он может просто хранить два
Set<Long>и обеспечить доступ к ним, но стоит им указать, что именно каждый из этих наборов и поэтому они группируются вместе.
чтобы дополнить ответ @maerics, вот
Comparableкортеж:import java.util.*; /** * A tuple of two classes that implement Comparable */ public class ComparableTuple<X extends Comparable<? super X>, Y extends Comparable<? super Y>> extends Tuple<X, Y> implements Comparable<ComparableTuple<X, Y>> { public ComparableTuple(X x, Y y) { super(x, y); } /** * Implements lexicographic order */ public int compareTo(ComparableTuple<X, Y> other) { int d = this.x.compareTo(other.x); if (d == 0) return this.y.compareTo(other.y); return d; } }
С Ломбок это легко объявить
Pairкласс:@Data(staticConstructor = "of") public class Pair<A, B> { private final A left; private final B right; }это будет генерировать геттеры, статический конструктор с именем "of",
equals(),hashcode()иtoString().посмотреть
@Dataдокументация для получения дополнительной информации
можно использовать Google Guava Table
хотя статья довольно старая сейчас, и хотя я понимаю, что я не очень полезен, я думаю, что работа сделана здесь:http://www.pds.ewi.tudelft.nl/pubs/papers/cpe2005.pdf, было бы неплохо в основной Java.
вы можете делать вещи, как:
int a; char b; float c; [a,b,c] = [3,'a',2.33];или
[int,int,char] x = [1,2,'a'];или
public [int,boolean] Find(int i) { int idx = FindInArray(A,i); return [idx,idx>=0]; } [idx, found] = Find(7);вот кортежи:
- определяется как примитивные типы-нет шаблоны/дженерики
- стек-выделено, если объявлено локально
- назначено с помощью сопоставления с образцом
такой подход увеличивает
- производительность
- читабельности
- экспрессивность
я начну с общей точки зрения о кортежах в Java и закончу с импликацией для вашей конкретной проблемы.
1) то, как кортежи используются в неродовых языках, избегается в Java, потому что они не являются типобезопасными (например, в Python:
tuple = (4, 7.9, 'python')). Если вы все еще хотите использовать что-то вроде кортежа общего назначения (который не рекомендуется), вы должны использоватьObject[]илиList<Object>и бросить элементы после проверки сinstanceofдля обеспечения безопасность типов.обычно кортежи в определенной настройке всегда используются одинаково с содержимым одной и той же структуры. В Java, вы должны определить эту структуру явно в
classчтобы обеспечить четко определенные, типобезопасные значения и методы. Это кажется раздражающим и ненужным сначала, но предотвращает ошибки уже в времени компиляции.2) Если вам нужен кортеж, содержащий те же (супер-)классы
FooиспользуйтеFoo[],List<Foo>илиList<? extends Foo>(или неизменяемые аналоги списков). Поскольку кортеж не имеет определенной длины, это решение эквивалентно.3) в вашем случае, вы, кажется, нужно
Pair(т. е. кортеж четко определенной длины 2). Это делает ответ maerics или один из дополнительных ответов наиболее эффективным, поскольку вы можете повторно использовать код в будущем.
Comments