检测数组中的非空引用

时间:2011-01-18 22:43:54

标签: java arrays algorithm null

我刚刚问过a similar question,但后来我意识到我其实还需要别的东西。由于该问题已有两个答案,我不想编辑我的问题。所以这就是我真正需要的:


我想检测数组的子范围是否只包含 null引用。不知怎的,这样:

public static <T> boolean nullReferencesOnly
(T[] array, int fromInclusive, int toExclusive)
{
    for (int i = fromInclusive; i < toExclusive; ++i)
    {
        if (array[i] != null) return false;
    }
    return true;
}

在Java库中是否有这样的方法,所以我不必手动遍历数组?

5 个答案:

答案 0 :(得分:7)

Collections.frequency(Arrays.asList(array), null) == array.length

对于某个范围, SLaks 已在他的回答中提出.subList(from, to)

答案 1 :(得分:1)

您可以使用像Guava这样的函数式编程库(http://code.google.com/p/guava-libraries/)。你可以这样做:


import com.google.common.base.Predicate;

public class NotNull implements Predicate
{

    @Override
    public boolean apply(String arg0)
    {
        return arg0 != null;
    }

}

一个测试驱动程序,看看它是如何使用的:


import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.List;

import org.junit.Test;

import com.google.common.collect.Iterables;

public class Driver
{
    @Test
    public void testNotNull()
    {
        List l = Arrays.asList(new String[] {null, null, null});

        String s = Iterables.find(l, new NotNull(), null);

        assertNull(s);
    }

    @Test
    public void testNotNull2()
    {
        List l = Arrays.asList(new String[] {null, "1", null});

        String s = Iterables.find(l, new NotNull(), null);

        assertNotNull(s);
    }
}

有了这个,你只需调用Iterables.find()并查看它是否可以找到任何非null的东西。只要它不返回任何内容(null),就会知道列表中没有任何非空的内容。

答案 2 :(得分:1)

我认为最好的解决方案是获取您已经获得的代码,将数组类型更改为Object[]并将方法放入“帮助程序”类中。

  1. AFAIK,标准Java库中没有直接执行您想要的方法。
  2. AFAIK,Apache Commons或Google Collections / Guava中没有直接执行您想要的方法。
  3. 涉及Collection.contains的解决方案将失败,因为该方法基于equals,如果您测试null,则会提供NPE。
  4. 涉及通用frequency方法的解决方案在找到null时不会发生短路。
  5. 涉及应用Predicate对象的解决方案非常昂贵,并且需要的代码多于您的解决方案。
  6. 您的解决方案易于阅读,并且比任何提议的替代方案更有效。它涉及显式循环这一事实不应该与您有关。毕竟,这是您正在编写的Java代码...而不是FP语言。


    除此之外 - 如果问题是测试是否存在null元素(而不是非null元素),那么一个替代方案是org.springframework.util.Assert.noNullElements

    http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/Assert.html#noNullElements(java.lang.Object[]))
    

    然而,这会引发异常,而不是返回truefalse,这可能会使它成为一个糟糕的解决方案......除非您打算抛出异常。

答案 3 :(得分:0)

嗯,效率不高,但你可以使用Set帮助,比如这个例子:

  String[] test = {null, null, null, null};
  Set<String> set = new HashSet<String>(Arrays.asList(test));
  System.out.println(set.size() == 0 || (set.size() == 1 && set.contains(null)));

这样,如果它全部为null,它将只有一个元素,并且一个元素将为null。 如果您只需要一个范围,则可以在Arrays.asList(test)上使用subList。

效率不高,但使用可在核心Java库中找到的类。

希望这有帮助。

答案 4 :(得分:0)

直接使用Java 8(或更高版本)并使用短路;表示一旦检测到不为null的元素,它将立即返回:

public static boolean hasAtLeastOneElementNotNull(final Object[] array) {

    return Arrays.stream(array)
            .anyMatch(Objects::nonNull);
}

来自“ anyMatch”的文档:

  

返回此流的任何元素是否与提供的谓词匹配。 如果不一定要确定结果,则可能无法评估所有元素上的谓词。如果流为空,则返回false,并且不对谓词求值。   这是短路端子操作。