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

时间:2015-04-25 23:46:52

标签: java

我有一个类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?我想找到名称变量=“Ligurian”的位置,然后返回Ligurian.getOrigin()

3 个答案:

答案 0 :(得分:4)

使用流API:

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

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

考虑让这堂课来管理你的橄榄(或其他任何东西):

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的情况下要做什么。我不确定。可能需要使用类名在内部存储。