2016-02-28 50 views
1

我想創建具有兩個值的通用元組。例如一個具有兩個字符串或兩個整數的元組等(通用值)。但它不應該能夠混合兩個元素,例如一個字符串與一個整數(例如一個哈希映射)。創建具有相同類元素的通用元組

如何創建一個類型相同的元組?此刻,我爲元組中的兩個元素使用了通配符泛型參數,當然這不會強制開發人員爲這兩個元素使用相同的類類型。

import java.io.Serializable; 

public class Main { 
    class Element<T extends Comparable<?> & Serializable> { 
     private final T element; 

     public Element(T element) { 
      this.element = element; 
     } 

     public String raw() { 
      return element.toString(); 
     } 
    } 

    class Tuple<T extends Element<?>, U extends Element<?>> { 
     private final Element<?> element1; 
     private final Element<?> element2; 

     public Tuple(Element<?> element1, Element<?> element2) { 
      this.element1 = element1; 
      this.element2 = element2; 
     } 

     public Element<?> getElement1() { 
      return element1; 
     } 

     public Element<?> getElement2() { 
      return element2; 
     } 
    } 

    public static void main(String[] args) { 
     new Main(); 
    } 

    public Main() { 
     Element<String> element1 = new Element<String>(new String("First tuple element")); 
     Element<String> element2 = new Element<String>(new String("Second tuple element")); 
     Element<Integer> wrongelement = new Element<Integer>(42); // <-- Should not be possible, but it is... 
     Tuple<Element<String>, Element<String>> tuple = new Tuple<Element<String>, Element<String>>(element1, element2); 

     // First tuple element 
     System.out.println(tuple.getElement1().raw()); 

     // Second tuple element 
     System.out.println(tuple.getElement2().raw()); 
    } 
} 

回答

1

Tuple類簡單地只用一個通用的類型,有你的元素中的字段是通用型的,而不是超類(即T element1而不是Element<?> element1):

class Tuple<T extends Element<?>> { 

    private final T element1; 
    private final T element2; 

    public Tuple(T element1, T element2) { 
     this.element1 = element1; 
     this.element2 = element2; 
    } 

    public T getElement1() { 
     return element1; 
    } 

    public T getElement2() { 
     return element2; 
    } 
} 

然後你可以簡單地用一種類型的實例它是這樣:

public static void main(String... args) { 

    Element<String> element1 = new Element<String>(new String("First tuple element")); 
    Element<String> element2 = new Element<String>(new String("Second tuple element")); 

    Tuple<Element<String>> tuple = new Tuple<Element<String>>(element1, element2); 

    // First tuple element 
    System.out.println(tuple.getElement1().raw()); 

    // Second tuple element 
    System.out.println(tuple.getElement2().raw()); 
} 

順便說一句,你不必new String你的字符串,你可以簡單地p rovide其視爲常規字符串:

Element<String> element1 = new Element<String>("First tuple element"); 
Element<String> element2 = new Element<String>("Second tuple element"); 
+0

謝謝,我不知道爲什麼我沒有想到這一點。 – swaechter

1

看來你只是想這樣:

class Tuple<T extends Comparable<?> & Serializable> { 
    private final Element<T> element1; 
    private final Element<T> element2; 

    public Tuple(Element<T> element1, Element<T> element2) { 
     this.element1 = element1; 
     this.element2 = element2; 
    } 

    public Element<T> getElement1() { 
     return element1; 
    } 

    public Element<T> getElement2() { 
     return element2; 
    } 
} 

public Main() { 
    Element<String> element1 = new Element<>("First tuple element"); 
    Element<String> element2 = new Element<>("Second tuple element"); 
    Element<Integer> wrongelement = new Element<>(42); 

    // compiles fine 
    Tuple<String> tuple = new Tuple<>(element1, element2); 

    // doesn't compile 
    Tuple<String> tuple = new Tuple<>(element1, wrongelement); 
} 
+0

謝謝,我接受了另一個解答,因爲它是第一個。我也猜測返回T是更通用的,並簡化了代碼的重構(如果你想用AnotherElement替換Element)。另一方面,IDE支持可能會更好,因爲寫出返回元素。 – swaechter

+1

另一個答案看起來不對我。它允許這樣做,例如:'元組>元組=新元組>(element1,wrongelement);'。您似乎不想使用Element的子類參數化Tuple。你似乎想要一個包含相同泛型類型的兩個元素的元組。 –

0

在不重新發明輪子的利益,你可以考慮使用是已經存在的元組或對執行。 Apache的commons-lang庫,例如,包括Pair<R, L>實現,你可以通過它只是綁兩個泛型類型參數是相同的空類擴展...

import org.apache.commons.lang3.tuple.Pair 

public class MyPair<T> extends Pair<T, T> { } 

如果你真的想保持你的API,您可以非常簡單地使用Pair方法left()right()來實現這些方法。

相關問題