如何在Java中访问列表的第一个非空项?

如何在Java中访问列表的第一个非空项?,java,list,oop,null,java-8,Java,List,Oop,Null,Java 8,所以我有一个方法(我不能更改参数,或者通过HashMaps可以使这变得更容易…稍后将详细介绍),它将项作为参数传递。现在,我有一个来自另一个类的实例列表,其中一个属性与此项的类型相同,我想在列表中找到与此项对应的实例(其中应该只有一个)。这就是我找到这个的原因: List<Instance> instances = ... public static void checkItems(Item i) { List<Instance> n = new ArrayL

所以我有一个方法(我不能更改参数,或者通过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);

}
List实例=。。。
公共静态无效检查项目(项目一){
列表n=新的ArrayList();
forEach(p->n.add(p.i==i?p:null));
实例currentInstance=n.get(0);
//实例currentInstance=instances.stream().filter(p->p.i==i).collect(Collectors.toList()).get(0);
}
你可能会直接注意到两件事:

  • 我使用了一个条件运算符,当条件未通过时,它会向列表中添加一个空值
  • 我的注释代码是解决此问题的另一次尝试
  • 因此,在第一种情况下,我设置null是因为它需要您设置一些内容,而null值可能更容易使用,这就是为什么会出现这样的问题:如何访问列表中的第一个非null值(而不需要遍历整个列表来找到它

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

    请注意第二点:我试图用streams解决它的方法实际上完全按照计划工作,只是出于某种原因,恢复的实例列表不是原始实例的直接副本。这导致某些属性的值已重置为默认值,因此使此方法无效

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

    你可以像这样做

    instances.forEach(p -> {
       if (p.i == i) n.add(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();
    
    先选择=
    instances.stream().filter(p->p.i==i.findFirst();
    
    (其中应该只有一个)


    其中肯定只有一个,或者可能不止一个。(如果不止一个,那又怎样?这是一个错误吗?)听起来你应该有一个
    集合,而不是
    列表。只是一个观察。

    如果你知道只有一个
    p
    通过了测试,我不知道创建一个负载为
    null
    值加
    p
    的列表有什么意义

    您的问题似乎源于想要使用
    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.
    

    instances.forEach(p->if(p.i==i)n.add(p))我很难理解你的问题是什么,以及这个方法应该做什么。它不返回任何东西,也不修改任何状态,所以它什么也不做。@JBNizet这是因为它只是我正在编写的这件大事的一个片段,我不想因为编写所有其他毫无意义的代码而增加任何混乱是的,
    forEach()
    用于处理每个元素。它不是循环的替代品。这就是为什么我的第一个方法是使用流,但后来我发现属性有一个奇怪的问题(实际上可能与其他问题有关)。@Radiodef我从未使用过它。“我真的很喜欢我链接到的答案,尽管它更像是一种咆哮。”PaulBoddington我也从来没有想过要使用它,除非我的一位同学提醒我,我们的老师在课堂上给我们展示了它,提醒我们在可能的时候使用它。这可能只是因为我们还没有正式在类中看到流,所以现在它只是一个占位符
    forEach()
    更像是一个玩具。这只是一些非常简单的循环的方便语法。它比实际程序中的要复杂一点,我只想保留一点上下文,这就是我提到这些限制的原因。总而言之,我只是对如何解决这个特定的问题感兴趣好的,我不知道你可以使用这种语法,谢谢!Eclipse告诉我正确的语法是
    …(p->{if(p.i==i)n.add(p);})添加了
    }
    之前。我希望这是对的。。。