使用 Java 流检查 ArrayList 内容

Posted

技术标签:

【中文标题】使用 Java 流检查 ArrayList 内容【英文标题】:Check ArrayList content with Java stream 【发布时间】:2016-02-06 12:47:14 【问题描述】:

考虑以下 ArrayList:

[0] => Person
[1] => User
[2] => Dummy

如何使用 Java 流检查此数组列表是否包含除 PersonUser 之外的任何其他对象?

这样我就可以创建一个 if 语句,如果它包含 only PersonUser,则返回 null,或者如果它包含除 Person 或 @ 之外的任何其他对象,则返回 arraylist 本身987654327@像这样:

if( /*arrayList contains only Person and User*/ ) 
  return null;

else 
  //arrayList contains other objects besides Person and User
  return arrayList;

【问题讨论】:

为什么不使用instanceof 这是ArrayList<Object>(或ArrayList<?>)吗?你为什么使用原始类型? 是的,它是一个未指定对象类型的数组列表 【参考方案1】:

假设 PersonUser 是类型,而不是特定的对象,您可以这样做。

return list.stream()
           .filter(o -> !(o instanceof Person) && !(o instanceof User))
           .findAny()
           .isPresent() ? list : null;

【讨论】:

OP没有说明他使用的是Java8,所以你也应该提供一个pre-Java8的解决方案.. @hagrawal 他指定他想使用流。【参考方案2】:

替代保罗的回答(在你的问题中加上 if-else)

if (arrayList.stream().allMatch(o -> o instanceof Person || o instanceof User)) 
    return null;
 else 
    return arrayList;

【讨论】:

我更喜欢这个而不是我的答案,因为它不会创建一个无用的 Optional 对象。 @PaulBoddington 我也希望allMatch 本身比filter 更有效。它将在第一个可能是第一个元素的不匹配时提前返回。但是返回 ListOptional 而不是 null 或 List 会很有趣 filter().findAny() 也会提前返回。我同意返回 Listnull 有点奇怪。 通常建议返回一个空列表而不是null。我想说,与空列表相比,Optional<List> 并不比 null 好多少。 好吧,不建议使用Optional<List<…>>之类的东西。通常,您想返回Collections.emptyList() 或只是一个新列表,其中所有非法项目都已删除。返回null 或不存在的列表是一个相当不寻常的要求,因为这意味着调用者必须执行null 检查,因此有条件地不使用列表引用,与仅返回@ 相比,这并没有简化使用987654338@allMatch 的值。【参考方案3】:

使用过滤器

List<Object> objLst = new ArrayList<Object>(Arrays.asList(new Object[] new User(), new Person(), new Dummy() ));

return (objLst.stream()
    .filter(e -> !(e instanceof User || e instanceof Person))
    .limit(1)
    .count() > 0) ? null : objLst;

【讨论】:

.filter(…).count()&gt;0 在计数已经大于零时可能会浪费资源计数项目。 .filter(…).findAny().isPresent() 或更简单的.anyMatch(…) 是更好的选择,因为它们在遇到 one 匹配项后立即返回。如果您想保留基于count 的解决方案,您可以使用.filter(…).limit(1).count()&gt;0 改进它,这样它也会停止在第一个遇到的项目上。【参考方案4】:

我更喜欢不使用ìnstanceof 对类列表进行硬编码的解决方案,如

    List<Class<?>> clist = Arrays.asList(Person.class, User.class);
    List<?> list = Arrays.asList(new Person(),new User(),new Dummy());

    List<?> result =  list.stream()
            .map(Object::getClass)
            .anyMatch(x ->
                    clist.stream().
                            noneMatch(c->c.isAssignableFrom(x)))
            ? list : null;

【讨论】:

以上是关于使用 Java 流检查 ArrayList 内容的主要内容,如果未能解决你的问题,请参考以下文章

java怎么检查句子里的一个词是不是包含在arraylist里

Java的ArrayList实现

用java的io流,将一个文本框的内容反转

Java - 检查字符串的 ArrayList 是不是按字母顺序排列

java中使用ArrayList如何修改里面的内容.

使用 If 条件遍历 ArrayList 并使用流 api 返回布尔标志 [重复]