2011-05-15 95 views
30

什麼是Java中存儲在列表中的三重數據的最佳方式是什麼?Java:如何將數據三元存儲在列表中?

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

我通常使用HashMap的夫婦的數據鍵+值..我應該去爲HashMap + Arraylist?或ArrayList + ArrayList?

感謝

+3

或者創建包含三個對象的新類。你用它做什麼? – whirlwin 2011-05-15 19:58:09

回答

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; } 
} 

並以實例名單:

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

你應該做'a','b'和'c'決定。 – 2011-05-16 04:49:53

+3

equals和hashCode可能是不壞在這裏 – AvrDragon 2013-05-31 13:26:08

+0

爲什麼要干將如果A,B,C是不是私人的? – shinzou 2016-08-06 12:07:18

1

我似乎與whirlwin同意。

普遍的共識,雖然我現在不能找到證據規定,參數化類型應不超過2,這就是爲什麼每節課我能想到的在Java集合庫在有兩條按參數化類型。當你有三個參數化類型

代碼變得混亂。只是方式太多>,<來處理。

我建議whirlwin說什麼,並創建包含你所需要的三個特定類型的對象。

1

如果你希望跟蹤四個或更多的物體放在一起,尋找一些擴展。

如果你決定你想要一個三重的概念,得到一些想法,你可以跟隨太陽的圖案爲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); 
    } 
} 

或效仿谷歌的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

基於TripleImmutableTriple沒有依賴進口的Apache代碼。 L,M和R類型必須實現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); 
    } 
} 
相關問題