2011-05-15 12 views
30

¿Cuál es la mejor forma en que Java almacena los datos triples en una lista?Java: ¿cómo almacenar datos triples en una lista?

[a, b, c] 
[a, b, c] 
... 

lo general el uso HashMap para parejas de clave de datos + valor .. debería ir para HashMap + Arraylist? o ArrayList + ArrayList?

gracias

+3

O crear una nueva clase que posee los tres objetos. ¿Para qué lo estás usando? – whirlwin

Respuesta

42
public class Triplet<T, U, V> { 

    private final T first; 
    private final U second; 
    private final V third; 

    public Triplet(T first, U second, V third) { 
     this.first = first; 
     this.second = second; 
     this.third = third; 
    } 

    public T getFirst() { return first; } 
    public U getSecond() { return second; } 
    public V getThird() { return third; } 
} 

Y para crear instancias de la lista:

List<Triplet<String, Integer, Integer>> = new ArrayList<>(); 
+3

Debería hacer 'a',' b' y 'c' final. –

+3

equals y hashCode podrían no estar mal aquí – AvrDragon

+0

¿Por qué hacer getters si a, b, c no son privados? – shinzou

1

que parecen estar de acuerdo con whirlwin.

El consenso general, aunque no puedo encontrar evidencia ahora, estipula que los tipos parametrizados no deberían ser más de 2. Esta es la razón por la cual cada clase que puedo pensar en la biblioteca de colecciones Java tiene como máximo dos tipos parametrizados.

El código se satura cuando tiene tres tipos de parámetros. Demasiadas maneras, < para tratar.

Sugiero lo que dijo whirlwin y crear un objeto que contenga los tres tipos específicos que necesita.

1

Si espera seguir cuatro o más objetos juntos, busque algo que se pueda escalar.

Si se va a decidir que desea la noción de un triple, para obtener algunas ideas que puede seguir el modelo de Sun para javac.util.Pair:

public class Pair<A, B> { 

    public final A fst; 
    public final B snd; 

    public Pair(A fst, B snd) { 
     this.fst = fst; 
     this.snd = snd; 
    } 

    public String toString() { 
     return "Pair[" + fst + "," + snd + "]"; 
    } 

    private static boolean equals(Object x, Object y) { 
     return (x == null && y == null) || (x != null && x.equals(y)); 
    } 

    public boolean equals(Object other) { 
     return 
      other instanceof Pair<?,?> && 
      equals(fst, ((Pair<?,?>)other).fst) && 
      equals(snd, ((Pair<?,?>)other).snd); 
    } 

    public int hashCode() { 
     if (fst == null) return (snd == null) ? 0 : snd.hashCode() + 1; 
     else if (snd == null) return fst.hashCode() + 2; 
     else return fst.hashCode() * 17 + snd.hashCode(); 
    } 

    public static <A,B> Pair<A,B> of(A a, B b) { 
     return new Pair<A,B>(a,b); 
    } 
} 

o seguir de android.util.Pair

public class Pair<F, S> { 
    public final F first; 
    public final S second; 

    public Pair(F first, S second) { 
     this.first = first; 
     this.second = second; 
    } 

    public boolean equals(Object o) { 
     if (o == this) return true; 
     if (!(o instanceof Pair)) return false; 
     final Pair<F, S> other; 
     try { 
      other = (Pair<F, S>) o; 
     } catch (ClassCastException e) { 
      return false; 
     } 
     return first.equals(other.first) && second.equals(other.second); 
    } 

    public int hashCode() { 
     int result = 17; 
     result = 31 * result + first.hashCode(); 
     result = 31 * result + second.hashCode(); 
     return result; 
    } 
    //... 
} 
2

Basado en Triple Google y ImmutableTriple sin dependencias de importaciones del código de Apache. Los tipos L, M y R deben implementar la interfaz Comparable.

Triple.java

import java.io.Serializable; 

/** 
* <p>A triple consisting of three elements.</p> 
* <p/> 
* <p>This class is an abstract implementation defining the basic API. It refers to the elements as 
* 'left', 'middle' and 'right'.</p> 
* <p/> 
* <p>Subclass implementations may be mutable or immutable. However, there is no restriction on the 
* type of the stored objects that may be stored. If mutable objects are stored in the triple, then 
* the triple itself effectively becomes mutable.</p> 
* 
* @param <L> 
*   the left element type 
* @param <M> 
*   the middle element type 
* @param <R> 
*   the right element type 
* 
* @version $Id: Triple.java 1557584 2014-01-12 18:26:49Z britter $ 
* @since 3.2 
*/ 
public abstract class Triple<L, M, R> 
     implements Comparable<Triple<L, M, R>>, Serializable 
{ 

    /** 
    * Serialization version 
    */ 
    private static final long serialVersionUID = 1L; 


    /** 
    * <p>Obtains an immutable triple of from three objects inferring the generic types.</p> 
    * <p/> 
    * <p>This factory allows the triple to be created using inference to obtain the generic 
    * types.</p> 
    * 
    * @param <L> 
    *   the left element type 
    * @param <M> 
    *   the middle element type 
    * @param <R> 
    *   the right element type 
    * @param left 
    *   the left element, may be null 
    * @param middle 
    *   the middle element, may be null 
    * @param right 
    *   the right element, may be null 
    * 
    * @return a triple formed from the three parameters, not null 
    */ 
    public static <L, M, R> Triple<L, M, R> of(
      final L left, 
      final M middle, 
      final R right) 
    { 
     return new ImmutableTriple<L, M, R>(left, middle, right); 
    } 

    //----------------------------------------------------------------------- 


    /** 
    * <p>Gets the left element from this triple.</p> 
    * 
    * @return the left element, may be null 
    */ 
    public abstract L getLeft(); 

    /** 
    * <p>Gets the middle element from this triple.</p> 
    * 
    * @return the middle element, may be null 
    */ 
    public abstract M getMiddle(); 

    /** 
    * <p>Gets the right element from this triple.</p> 
    * 
    * @return the right element, may be null 
    */ 
    public abstract R getRight(); 

    //----------------------------------------------------------------------- 


    /** 
    * <p>Compares the triple based on the left element, followed by the middle element, finally the 
    * right element. The types must be {@code Comparable}.</p> 
    * 
    * @param other 
    *   the other triple, not null 
    * 
    * @return negative if this is less, zero if equal, positive if greater 
    */ 
    @Override 
    public int compareTo(final Triple<L, M, R> other) 
    { 
     @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc 
     final Comparable<Object> comparableLeft = (Comparable<Object>) getLeft(); 
     int cmpLeft = comparableLeft.compareTo(other.getLeft()); 

     if (cmpLeft != 0) { 
      return cmpLeft; 
     } 

     @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc 
     final Comparable<Object> comparableMidle = (Comparable<Object>) getMiddle(); 
     int cmpMidle = comparableMidle.compareTo(other.getMiddle()); 

     if (cmpMidle != 0) { 
      return cmpMidle; 
     } 

     @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc 
     final Comparable<Object> comparableRight = (Comparable<Object>) getRight(); 
     int cmpRight = comparableRight.compareTo(other.getRight()); 

     return cmpRight; 
    } 


    /** 
    * <p>Compares this triple to another based on the three elements.</p> 
    * 
    * @param obj 
    *   the object to compare to, null returns false 
    * 
    * @return true if the elements of the triple are equal 
    */ 
    @Override 
    public boolean equals(final Object obj) 
    { 
     if (obj == null) { 
      return false; 
     } 
     if (obj == this) { 
      return true; 
     } 
     if (obj instanceof Triple<?, ?, ?>) { 
      final Triple<?, ?, ?> other = (Triple<?, ?, ?>) obj; 


      return equals(getLeft(), other.getLeft()) && 
        equals(getMiddle(), other.getMiddle()) && 
        equals(getRight(), other.getRight()); 
     } 
     return false; 
    } 


    private boolean equals(
      final Object object1, 
      final Object object2) 
    { 
     return !(object1 == null || object2 == null) && 
       (object1 == object2 || object1.equals(object2)); 
    } 


    /** 
    * <p>Returns a suitable hash code.</p> 
    * 
    * @return the hash code 
    */ 
    @Override 
    public int hashCode() 
    { 
     return (getLeft() == null ? 0 : getLeft().hashCode())^
       (getMiddle() == null ? 0 : getMiddle().hashCode())^
       (getRight() == null ? 0 : getRight().hashCode()); 
    } 


    /** 
    * <p>Returns a String representation of this triple using the format {@code 
    * ($left, $middle, $right)}.</p> 
    * 
    * @return a string describing this object, not null 
    */ 
    @Override 
    public String toString() 
    { 
     return new StringBuilder().append('(') 
       .append(getLeft()) 
       .append(',') 
       .append(getMiddle()) 
       .append(',') 
       .append(getRight()) 
       .append(')') 
       .toString(); 
    } 


    /** 
    * <p>Formats the receiver using the given format.</p> 
    * <p/> 
    * <p>This uses {@link java.util.Formattable} to perform the formatting. Three variables may be 
    * used to embed the left and right elements. Use {@code %1$s} for the left element, {@code 
    * %2$s} for the middle and {@code %3$s} for the right element. The default format used by 
    * {@code toString()} is {@code (%1$s,%2$s,%3$s)}.</p> 
    * 
    * @param format 
    *   the format string, optionally containing {@code %1$s}, {@code %2$s} and {@code %3$s}, 
    *   not null 
    * 
    * @return the formatted string, not null 
    */ 
    public String toString(final String format) 
    { 
     return String.format(format, getLeft(), getMiddle(), getRight()); 
    } 
} 

ImmutableTriple.java

public final class ImmutableTriple<L, M, R> extends Triple<L, M, R> { 

    /** Serialization version */ 
    private static final long serialVersionUID = 1L; 

    /** Left object */ 
    public final L left; 
    /** Middle object */ 
    public final M middle; 
    /** Right object */ 
    public final R right; 

    /** 
    * <p>Obtains an immutable triple of from three objects inferring the generic types.</p> 
    * 
    * <p>This factory allows the triple to be created using inference to 
    * obtain the generic types.</p> 
    * 
    * @param <L> the left element type 
    * @param <M> the middle element type 
    * @param <R> the right element type 
    * @param left the left element, may be null 
    * @param middle the middle element, may be null 
    * @param right the right element, may be null 
    * @return a triple formed from the three parameters, not null 
    */ 
    public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) { 
     return new ImmutableTriple<L, M, R>(left, middle, right); 
    } 

    /** 
    * Create a new triple instance. 
    * 
    * @param left the left value, may be null 
    * @param middle the middle value, may be null 
    * @param right the right value, may be null 
    */ 
    public ImmutableTriple(final L left, final M middle, final R right) { 
     super(); 
     this.left = left; 
     this.middle = middle; 
     this.right = right; 
    } 

    //----------------------------------------------------------------------- 
    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public L getLeft() { 
     return left; 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public M getMiddle() { 
     return middle; 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public R getRight() { 
     return right; 
    } 
} 
6
public class Triple<F, S, T> { 

    public final F first; 
    public final S second; 
    public final T third; 

    public Triple(F first, S second, T third) { 
     this.first = first; 
     this.second = second; 
     this.third = third; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (!(o instanceof Triple)) { 
      return false; 
     } 
     Triple<?, ?, ?> p = (Triple<?, ?, ?>) o; 
     return first.equals(p.first) && second.equals(p.second) && third.equals(p.third); 
    } 

    private static boolean equals(Object x, Object y) { 
     return (x == null && y == null) || (x != null && x.equals(y)); 
    } 

    @Override 
    public int hashCode() { 
     return (first == null ? 0 : first.hashCode())^(second == null ? 0 : second.hashCode())^(third == null ? 0 : third.hashCode()); 
    } 

    public static <F, S, T> Triple <F, S, T> create(F f, S s, T t) { 
     return new Triple<F, S, T>(f, s, t); 
    } 
} 
Cuestiones relacionadas