我的问题很清楚。
我有一个列表,我想确保它至少有一个非null元素。而且,没有循环(性能测量)。
list.size()
绝对没有帮助。因为如果列表包含5个空值,那么它的大小也将是5。
请注意,我不是要求一个不能包含null
的列表。
答案 0 :(得分:7)
没有循环的标准List
实现无法显式或隐式 1 。 List
API不支持此功能,并且没有任何标准列表类作为专门操作包含。
避免循环的唯一方法是创建一个自定义List
实现,将null
视为特殊,并保留列表中null
元素数量的计数。这种方法的缺点是列表上的更新操作更加昂贵,因为他们需要测试以查看计数器是否需要更改。
请注意,使用手动编码循环通常并不昂贵,因为只要看到非null元素就可以停止循环。
1 - 如果你担心效率,那么像Collections.frequency
这样的方法中的隐式循环可能比为此目的明确的手动循环要贵得多。
<强>后续强>
我没有创建或填写列表。我从一些我无法改变的代码中获得了已生成的列表。
在这种情况下,像下面这样的循环是最快的解决方案:
boolean empty = true;
for (SomeType t : list) {
if (t != null) {
empty = false;
break;
}
}
如果列表是ArrayList
,则索引可能稍微快一点,但LinkedList
不能。
答案 1 :(得分:6)
您可以创建自己的列表实现,将非空元素的数量保留在局部变量中,并在每次添加和删除元素时更新它。
答案 2 :(得分:3)
如果您收到一个对象,您只知道它是一个列表(即它实现List
),那么您没有其他直接或间接循环的解决方案。
List
interface没有提供此类功能,我知道没有提供它的常用实现。
除了循环或调用循环方法之外别无选择。
编辑:当然,如果你自己编写列表类,你可以做你想要的计数器。
答案 3 :(得分:0)
Collections.frequency(list, null) > 0
答案 4 :(得分:0)
我不确定ArrayList
的拷贝构造函数是否实际上是循环的,但是这样做了,我的示例使用String
。另一方面,removeAll
在内部循环...所以这并不是真的“不循环”...
List<String> testLst = new ArrayList<String>();
testLst.add(null);
testLst.add(null);
testLst.add(null);
testLst.add(null);
List<String> testLst2 = new ArrayList<String>();
testLst2.add(null);
testLst2.add(null);
testLst2.add(null);
testLst2.add(null);
testLst2.add("test");
List<String> nullLst = new ArrayList<String>();
nullLst.add(null);
List<String> removedNull = new ArrayList<String>(testLst);
removedNull.removeAll(nullLst);
if (testLst.size() > 0 && removedNull.size() > 0) {
System.out.println("Contains non-null");
} else {
System.out.println("Contains only null or empty");
}
removedNull = new ArrayList<String>(testLst2);
removedNull.removeAll(nullLst);
if (testLst2.size() > 0 && removedNull.size() > 0) {
System.out.println("Contains non-null");
} else {
System.out.println("Contains only null or empty");
}
答案 5 :(得分:-1)
这是一个错误的问题。您无法判断列表是否包含null
元素而不查看元素。我可以使用递归给出一个答案,但这样做性能较差,只是绕过使用任何循环语句。
你想要的是一个首先不允许null的集合,或者创建一个实现列表接口的类,并跟踪私有字段中是否包含空值。