如何迭代自定义类型并找到特定类型



我有一个Olive:类的ArrayList

ArrayList<Olive> olives = new ArrayList<Olive>();
olives.add(new Kalamata());
olives.add(new Ligurian());
olives.add(new Kalamata());
olives.add(new Ligurian());

在kalamata和ligurian类中,我设置了它们的名称:

this.name = "Ligurian";
this.name = "Kalamata";

如何迭代Olive类型的arrayList?我想找到name variable="Ligurian"的位置,然后返回Ligurian.getOrigin()

使用流API:

Olive olive = olives.stream()
.filter(o -> o.name.equals("Ligurian"))
.findAny().get();
String origin = olive.getOrigin();

如果你使用的是Java7,你可以使用一个循环,这对你来说很遗憾,但也可以:

Olive found;
for(Olive olive : olives) {
if(olive.name.equals("Ligurian")) {
found = olive;
break;
}
}
String origin = found.getOrigin();

在Java中,迭代一个自定义类型并选择一个。

for (Olive olive : olives) {
if (olive instanceof Ligurian) {
String origin = olive.getOrigin();
}
}

考虑用这个类来管理你的橄榄(或其他任何东西):

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TypedList<T> {
Map<Class<? extends T>,List<T>> mlt;
public TypedList() {
mlt = new HashMap<>();
}
private <U extends T> void add(Class<U> t,U o) {
List<U> lu = (List<U>)mlt.get(t);
if (lu == null) {
lu = new ArrayList<>();
mlt.put(t, (List<T>)lu);
}
lu.add(o);
}
public void add(T o) {
add((Class<T>)o.getClass(),o);
}
public <U extends T> List<U> get(Class<U> t) {
return (List<U>)mlt.get(t);
}
public <U extends T> List<? extends U> getIncludingDescendands(Class<U> t) {
List<U> nl = new ArrayList<>();
// Inefficient Unions
mlt.entrySet().stream().filter((e)->t.isAssignableFrom(e.getKey())).forEach((e)->{nl.addAll((List<U>)e.getValue());});
return nl;
}
}

然后你的主代码可能看起来像这样:

public class Main {
public static void main(String[] args) {
TypedList<Olive> olives = new TypedList<>();
olives.add(new Kalamata());
olives.add(new Ligurian());
olives.add(new Kalamata());
olives.add(new Ligurian());
olives.add(new BigKalamata());
System.out.println("Number of Ligurian: "+olives.get(Ligurian.class).size());
System.out.println("Number of Kalamata: "+olives.get(Kalamata.class).size());
System.out.println("Number of BigKalamata: "+olives.get(BigKalamata.class).size());
System.out.println("Number of Kalamata and Subspecies: "+olives.getIncludingDescendands(Kalamata.class).size());
// get first Ligurian:
Ligurian ligurian = olives.get(Ligurian.class).get(0); // Carefull for NPE
}
}

还应考虑遵循

public interface Olive {}
public class Ligurian implements Olive {}
public class Kalamata implements Olive {}
public class BigKalamata extends Kalamata {}

请注意,作为一个附加功能,即使没有暴露getName,这也可以工作。它不使用getName,而是使用添加对象的类来进行子分类或分区。使用实际类名(如使用olives.get(Ligurian.class)时)会带来额外的好处,即在编译时会发现拼写错误,并且返回的对象是强类型的。

如果这样做的开销可以忽略不计,那么在积累数据时最好组织数据。这将使以后的处理效率更高(如果代码正确的话)。预见你以后将如何使用它会有所帮助。

可能还需要一个额外的想法,那就是在多个ClassLoader的情况下应该做什么。我不确定。可能需要使用类名进行内部存储。

相关内容

  • 没有找到相关文章

最新更新