Java 使用相同的类元素创建泛型元组

Java 使用相同的类元素创建泛型元组,java,generics,tuples,containers,Java,Generics,Tuples,Containers,我想创建一个具有两个值的通用元组。例如,具有两个字符串或两个整数等的元组(通用值)。但它不应该能够混合这两个元素,例如字符串和整数(例如哈希映射) 如何创建类型相同的元组?目前,我对元组中的两个元素都使用了通配符泛型参数,当然这并不强制开发人员对这两个元素使用相同的类类型 import java.io.Serializable; public class Main { class Element<T extends Comparable<?> & Serial

我想创建一个具有两个值的通用元组。例如,具有两个字符串或两个整数等的元组(通用值)。但它不应该能够混合这两个元素,例如字符串和整数(例如哈希映射)

如何创建类型相同的元组?目前,我对元组中的两个元素都使用了通配符泛型参数,当然这并不强制开发人员对这两个元素使用相同的类类型

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());
    }
}
import java.io.Serializable;
公共班机{
类元素,U扩展元素>{
私人最终要素1;
私人最终要素2;
公共元组(元素element1、元素element2){
this.element1=element1;
this.element2=element2;
}
公共元素getElement1(){
返回元素1;
}
公共元素getElement2(){
返回元素2;
}
}
公共静态void main(字符串[]args){
新的Main();
}
公用干管(){
Element element1=新元素(新字符串(“第一个元组元素”);
Element element2=新元素(新字符串(“第二个元组元素”);

Element ErrorElement=new Element(42);//只需在
元组
类中使用一个泛型类型,并使元素字段为该泛型类型,而不是超类(即
T element1
元素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); 
}

<代码>类元组> P>为了不重新发明轮子,你可以考虑使用一个现存的元组或配对实现。例如,Apache的库包括一个实现,你可以通过一个空的类来扩展,它只是把两个泛型类型的参数联系在一起……
import org.apache.commons.lang3.tuple.Pair

public class MyPair<T> extends Pair<T, T> { }
import org.apache.commons.lang3.tuple.Pair
公共类MyPair扩展了对{}

如果您真的想保留您的API,您可以非常简单地按照成对方法
left()
right()实现这些方法

谢谢,我不知道为什么我没有考虑这个问题。谢谢,我接受了另一个答案作为解决方案,因为它是第一个答案。我还认为返回t更通用,并简化了代码重构(如果您想用另一个元素替换元素)。另一方面,IDE支持对于写出的返回元素可能更好。另一个答案在我看来是错误的。它允许这样做,例如:
Tuple>(element1,ErrorElement);
。您似乎不希望用Element的子类参数化Tuple。您似乎希望Tuple包含两个相同泛型类型的元素。
Element<String> element1 = new Element<String>("First tuple element");
Element<String> element2 = new Element<String>("Second tuple element");
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); 
}
import org.apache.commons.lang3.tuple.Pair

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