Java 获取列表中元素的类型

Java 获取列表中元素的类型,java,list,generics,Java,List,Generics,我有两个不同的清单: List<MyFirstClass> list1; List<MySecondClass> list2; 但是现在我需要检查?是什么类型,以便在与给定的列表元素类型相关的方法中做出细微的区别 我该怎么做?还是有更好的方法 谢谢 编辑 这两个方法实际上是相同的,只是one方法调用list1.method1()和list2.method2()。这就是为什么我不想使用两种不同的方法。您可以使用继承来解决您的问题。为此,使两个类都从公共基类(或接口)继承。

我有两个不同的清单:

List<MyFirstClass> list1;
List<MySecondClass> list2;
但是现在我需要检查
是什么类型,以便在与给定的列表元素类型相关的方法中做出细微的区别

我该怎么做?还是有更好的方法

谢谢

编辑
这两个方法实际上是相同的,只是one方法调用
list1.method1()
list2.method2()
。这就是为什么我不想使用两种不同的方法。

您可以使用继承来解决您的问题。为此,使两个类都从公共基类(或接口)继承。然后创建一个列表来存储子类的元素。在子类中存储特定于每种类型的特殊逻辑。以下是一个例子:

class BaseClass {
  public void foo() {}
}

class ClassA extends BaseClass {
  public void foo() { /* ClassA logic here */ }
}

class ClassB extends BaseClass {
  public void foo() { /* ClassB logic here */ }
}

List<BaseClass> list = new ArrayList<BaseClass>();
list.add(new ClassA());
list.add(new ClassB());
for(BaseClass element : list) {
  element.foo();
}
类基类{
公共void foo(){}
}
ClassA类扩展了基类{
public void foo(){/*此处为ClassA逻辑*/}
}
类B扩展了基类{
public void foo(){/*此处为ClassB逻辑*/}
}
列表=新的ArrayList();
添加(新的ClassA());
添加(新类b());
for(基类元素:列表){
元素foo();
}

您可以使用继承来解决您的问题。为此,使两个类都从公共基类(或接口)继承。然后创建一个列表来存储子类的元素。存储子类中特定于每种类型的特殊逻辑。以下是一个例子:

class BaseClass {
  public void foo() {}
}

class ClassA extends BaseClass {
  public void foo() { /* ClassA logic here */ }
}

class ClassB extends BaseClass {
  public void foo() { /* ClassB logic here */ }
}

List<BaseClass> list = new ArrayList<BaseClass>();
list.add(new ClassA());
list.add(new ClassB());
for(BaseClass element : list) {
  element.foo();
}
类基类{
公共void foo(){}
}
ClassA类扩展了基类{
public void foo(){/*此处为ClassA逻辑*/}
}
类B扩展了基类{
public void foo(){/*此处为ClassB逻辑*/}
}
列表=新的ArrayList();
添加(新的ClassA());
添加(新类b());
for(基类元素:列表){
元素foo();
}

字面解决方案是使用
instanceof
来区分对象的类型

private void myMethod(List<?> list) {
    for(Object o : list) {
        if(o instanceof MyFirstClass) {
            MyfirstClass p = (MyFirstClass)o;
            p.myFirstMethod();
        } else if(o instanceof MySecondClass) {
            MySecondClass p = (MyFirstClass)o;
            p.mySecondMethod();
        }
    }
}

字面解决方案是使用
instanceof
来区分对象的类型

private void myMethod(List<?> list) {
    for(Object o : list) {
        if(o instanceof MyFirstClass) {
            MyfirstClass p = (MyFirstClass)o;
            p.myFirstMethod();
        } else if(o instanceof MySecondClass) {
            MySecondClass p = (MyFirstClass)o;
            p.mySecondMethod();
        }
    }
}

您不能根据
列表中的类型直接调整方法。不过,还有其他方法可以得到你想要的。这里有一种方法(这些名字会很糟糕,因为我没有太多的上下文来解释你要做的事情):


现在要调用您的方法,您可以使用
myMethod(list1,new classcaller())
myMethod(list2,new Class2Caller())
您不能直接根据
列表中的类型调整方法。不过,还有其他方法可以得到你想要的。这里有一种方法(这些名字会很糟糕,因为我没有太多的上下文来解释你要做的事情):


现在,要调用方法,您可以使用
myMethod(list1,newclass1 caller())
myMethod(list2,newclass2caller())

您可以使用lambda提取不同的调用并将其作为参数传递给方法:

private <T> myMethod(List<? extends T> myList, Consumer<T> method) {
    for (T item : myList) {
        // some stuff
        method.accept(item);
    }
}
这假设您正在调用0-arg、
void
方法。如果不是这样,您可以使用lambda,和/或使用另一个或创建自己的lambda


请注意,这本质上是更简洁的版本。

您可以使用lambda提取不同的调用,并将其作为参数传递给您的方法:

private <T> myMethod(List<? extends T> myList, Consumer<T> method) {
    for (T item : myList) {
        // some stuff
        method.accept(item);
    }
}
这假设您正在调用0-arg、
void
方法。如果不是这样,您可以使用lambda,和/或使用另一个或创建自己的lambda


请注意,这本质上是一个更简洁的版本。

虽然您可以使用
.getClass()
instanceof
、或
Class
参数,但这些参数往往会导致丑陋、脆弱的代码。如果你能帮忙,请不要去那里

方法#1 最好的方法是使用抽象类或接口将所需的逻辑放入列表项中。列表对象将直接执行所需的任何操作

最初的帖子似乎表明这是不可能的,所以让我们继续讨论方法2

方法#2 使用函数参数

public <T> String myMethod(List<T> myList, Function<T, String> func)
公共字符串myMethod(列表myList,函数func)
该函数将作用于列表中的每个项,并返回您的方法可以处理的内容

方法#3 使用包装类。您可以将每个列表项包装在知道如何处理它们的类中。包装器类将全部从单个基类继承,从而使您的方法如下所示:

myMethod(list1, MyFirstClass::method1);
myMethod(list2, MySecondClass::method2);
public String myMethod(List<Wrapper> myList)
公共字符串myMethod(列表myList)

虽然您可以使用
.getClass()
instanceof
参数,但这些参数往往会产生难看、脆弱的代码。如果你能帮忙,请不要去那里

方法#1 最好的方法是使用抽象类或接口将所需的逻辑放入列表项中。列表对象将直接执行所需的任何操作

最初的帖子似乎表明这是不可能的,所以让我们继续讨论方法2

方法#2 使用函数参数

public <T> String myMethod(List<T> myList, Function<T, String> func)
公共字符串myMethod(列表myList,函数func)
该函数将作用于列表中的每个项,并返回您的方法可以处理的内容

方法#3 使用包装类。您可以将每个列表项包装在知道如何处理它们的类中。包装器类将全部从单个基类继承,从而使您的方法如下所示:

myMethod(list1, MyFirstClass::method1);
myMethod(list2, MySecondClass::method2);
public String myMethod(List<Wrapper> myList)
公共字符串myMethod(列表myList)

instanceof
是您的领导者吗需要在泛型中检查
是一个很好的证据,表明该方法首先不是泛型的理想候选方法。您最好使用两种方法,它们可能通过调用公共私有方法共享公共逻辑。如果没有更多的代码,很难有意义地回答。@Yahya不,
instanceof
是您的敌人。它会导致脆弱的OOP、难以扩展和容易出错的程序。请不要鼓励学习型开发人员依赖