如何访问Java中List的第一个非null项



所以我有一个方法(我不能更改它的参数,否则可以通过HashMaps使其更容易…稍后会详细介绍),它将一个项作为参数传递。现在我有一个来自另一个类的实例列表,其中一个属性与该项的类型相同,我想在列表中找到与该项对应的实例(应该只有一个)。这就是我所做的发现:

List<Instance> instances = ...
public static void checkItems(Item i) {
    List<Instance> n = new ArrayList<>();
    instances.forEach(p -> n.add(p.i == i ? p : null));
    Instance currentInstance = n.get(0); 
    //Instance currentInstance = instances.stream().filter(p -> p.i == i).collect(Collectors.toList()).get(0);
}

你可能会直接注意到两件事:

  1. 我使用了一个条件运算符,当条件未通过时,它会向列表中添加一个null值
  2. 我的注释代码是解决此问题的又一次尝试

所以在第一种情况下,我放null是因为它需要你放一些东西,而null值可能更容易使用,这就是为什么会出现问题:我如何访问列表中的第一个非null值(而不需要迭代整个列表来找到它…)?

您可能会注意到,我只是将带有n.get(0)的列表的第一个值分配给currentInstance,因为我知道只有一个值通过了测试。但是,由于我应用于currentInstance的某些其他代码,该值不能为null。

关于第二点,请注意:我试图用流解决问题的方式实际上与计划完全一样,只是由于某种原因,恢复的实例列表不是原始实例的直接副本。这导致一些属性为的值被重置为默认值,因此使此方法变得无用。

编辑:我只是想提一下,streams方法不起作用,因为我在另一个类中犯了一些愚蠢的错误,代码没有任何问题,所以我将使用这一点来解决我的问题:D

如果你知道只有一个p通过了测试,我不知道创建一个包含null值和p的列表有什么意义。

你的问题似乎源于想要使用forEach。在我看来,你几乎应该总是使用for循环,而不是forEach。使用一个简单的for循环,您可以在找到项目时使用break

详细信息:

Instance p = null;
for (Instance q : instances) {
    if (q.i == i) {
        p = q;
        break;
    }
}
if (p == null)
    throw new IllegalStateException();   // It wasn't there.
// Do something with p.

你可以这样做:

Instance currentInstance = instances.stream()
    .filter(p -> p.i == i)
    .findFirst()
    .get(); // you can use get if you are sure there's one instance

谓词p -> p.i == i似乎可疑。为什么不使用equals()

如前所述,这通常可以通过以下方式使用流来解决:

Optional<Instance> first =
    instances.stream().filter(p -> p.i == i).findFirst();

(应该只有一个)

其中有肯定只有一个,或者其中有可能不止一个。(如果不止一个,那怎么办?这是错误吗?)听起来你应该有一个Set<Instance>,而不是List<Instance>。只是观察。

你可以像一样完成

instances.forEach(p -> {
   if (p.i == i) n.add(p);
});

最新更新