Использование пар или 2-кортежей в Java [дубликат]



этот вопрос уже есть ответ здесь:



моя хэш-таблица в Java выиграет от значения, имеющего структуру кортежа. Какие структуры данных я могу использовать в Java для этого?



Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ...
819   14  

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.

Если вы ищете встроенный Java двухэлементный кортеж, попробуйте AbstractMap.SimpleEntry.

в качестве расширения к @ 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 намекает на:

http://groups.google.com/group/comp.lang.java.help/browse_thread/thread/f8b63fc645c1b487/1d94be050cfc249b

эта дискуссия продолжает отражать подходы maerics vs ColinD: "должен ли я повторно использовать Кортеж класса с неспецифическим именем или создавать новый класс с конкретными именами каждый раз, когда я сталкиваюсь с этой ситуацией". Много лет назад я был в последнем лагере; я превратился в поддержку первого.

Android Tuple Utils

этот объект обеспечивает разумную реализацию 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

    Ничего не найдено.