【发布时间】:2011-07-28 02:25:42
【问题描述】:
在 Java 中,我有一个字符串数组列表,例如:
[,Hi, ,How,are,you]
我想去掉null和empty元素,怎么改成这样:
[Hi,How,are,you]
【问题讨论】:
在 Java 中,我有一个字符串数组列表,例如:
[,Hi, ,How,are,you]
我想去掉null和empty元素,怎么改成这样:
[Hi,How,are,you]
【问题讨论】:
List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
System.out.println(list);
list.removeAll(Arrays.asList("", null));
System.out.println(list);
输出:
[, Hi, null, How]
[Hi, How]
【讨论】:
java.util.AbstractList.remove()给我UnsupportedOperationException...
util或awt库中导入吗?
这是一个很晚的答案,但您也可以使用Collections.singleton:
List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
list.removeAll(Collections.singleton(null));
list.removeAll(Collections.singleton(""));
【讨论】:
现在我们有了 Java 8 lambda 表达式的另一种方法。
arrayList.removeIf(item -> item == null || "".equals(item));
【讨论】:
arrayList.removeIf(Strings::isNullOrEmpty);.
arrayList.removeIf(StringUtils::isEmpty);
arrayList.removeIf(StringUtils::isBlank);
arrayList.removeIf(String::isBlank);
如果您询问如何删除空字符串,您可以这样做(其中l 是ArrayList<String>) - 这会删除所有null 引用和长度字符串0:
Iterator<String> i = l.iterator();
while (i.hasNext())
{
String s = i.next();
if (s == null || s.isEmpty())
{
i.remove();
}
}
不要将ArrayList 与数组混淆,ArrayList 是一种动态数据结构,可根据其内容调整大小。如果你使用上面的代码,你不需要做任何事情来得到你描述的结果——如果你的 ArrayList 是 ["","Hi","","How","are" ,"you"], 如上所述删除后,它将正是您所需要的 - ["Hi","How","are","you"].
但是,如果您必须拥有原始列表的“净化”副本(同时保持原样)并通过 '将其存储回来'你的意思是'制作一个副本',那么krmby在另一个答案中的代码会很好地为你服务。
【讨论】:
remove() 是在 Iterator 而不是 ArrayList 上调用的
null 和空字符串。
如果您使用的是 Java 8,请尝试使用 lambda 表达式和 org.apache.commons.lang.StringUtils,这也将清除 array 输入中的 null 和 blank 值
public static String[] cleanArray(String[] array) {
return Arrays.stream(array).filter(x -> !StringUtils.isBlank(x)).toArray(String[]::new);
}
【讨论】:
filter(StringUtils::isNotBlank)
您可以使用几种方法:
遍历列表,为要删除的列表元素调用Iterator.remove()。这是最简单的。
反复拨打List.remove(Object)。这也很简单,但性能最差……因为您反复扫描整个列表。 (但是,这可能是其迭代器不支持 remove 的可变列表的一个选项...由于某种原因。)
创建一个新列表,遍历旧列表,将要保留的元素添加到新列表中。
如果无法返回新列表,如上3.然后清除旧列表并使用addAll将新列表的元素添加回它。
哪一个最快取决于原始列表的类、其大小以及需要删除的元素数量。以下是一些因素:
对于ArrayList,每个单独的remove 操作为O(N),其中N 是列表大小。使用Iterator.remove() 方法(或ArrayList.remove(element) 方法)从大型ArrayList 中删除多个元素的成本很高。
相比之下,LinkedList 的 Iterator.remove 方法是 O(1)。
对于ArrayList,创建和复制一个列表是O(N) 和相对便宜,特别是如果你可以确保目标列表的容量足够大(但不是太大)。
相比之下,创建和复制到LinkedList 也是O(N),但要贵得多。
所有这些加起来就是一个相当复杂的决策树。如果列表很小(比如 10 个或更少的元素),您可能可以使用上述任何方法。如果列表可能很大,您需要权衡列表中的所有问题,包括预期的列表大小和预期的移除数量。 (否则你可能会得到二次性能。)
【讨论】:
要把这个小金块放在这里:
Stream.of("", "Hi", null, "How", "are", "you")
.filter(t -> !Strings.isNullOrEmpty(t))
.collect(ImmutableList.toImmutableList());
我衷心希望 Java 有一个 filterNot。
【讨论】:
public static void listRemove() {
List<String> list = Arrays.asList("", "Hi", "", "How", "are", "you");
List<String> result = new ArrayList<String>();
for (String str : list) {
if (str != null && !str.isEmpty()) {
result.add(str);
}
}
System.out.println(result);
}
【讨论】:
java.lang.NullPointerException,因为str 可能是null。
如果您使用上述答案之一得到UnsupportedOperationException,并且您的List 是从Arrays.asList() 创建的,那是因为您无法编辑此类List。
要修复,请将Arrays.asList() 包裹在new LinkedList<String>() 中:
List<String> list = new LinkedList<String>(Arrays.asList(split));
来源来自这个answer。
【讨论】:
关于 Andrew Mairose 的评论 - 虽然是一个很好的解决方案,但我想补充一点,此解决方案不适用于 固定大小 列表。
您可以尝试这样做:
Arrays.asList(new String[]{"a", "b", null, "c", " "})
.removeIf(item -> item == null || "".equals(item));
但是你会遇到一个UnsupportedOperationException at java.util.AbstractList.remove(因为asList 返回一个不可调整大小的列表)。
一个不同的解决方案可能是这样的:
List<String> collect =
Stream.of(new String[]{"a", "b", "c", null, ""})
.filter(item -> item != null && !"".equals(item))
.collect(Collectors.toList());
这将产生一个很好的字符串列表:-)
【讨论】:
ArrayList,它不是固定大小。
private List cleanInputs(String[] inputArray) {
List<String> result = new ArrayList<String>(inputArray.length);
for (String input : inputArray) {
if (input != null) {
String str = input.trim();
if (!str.isEmpty()) {
result.add(str);
}
}
}
return result;
}
【讨论】:
List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", "", "How"));
Stream<String> stream = list .stream();
Predicate<String> empty = empt->(empt.equals(""));
Predicate<String> emptyRev = empty.negate();
list= stream.filter(emptyRev).collect(Collectors.toList());
或
list = list .stream().filter(empty->(!empty.equals(""))).collect(Collectors.toList());
【讨论】:
lukastymo 的回答似乎是最好的。
但由于它的可扩展性,这种方法也值得一提:
List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How", "are"));
list = list.stream()
.filter(item -> item != null && !item.isEmpty())
.collect(Collectors.toList());
System.out.println(list);
我的意思是你可以添加额外的过滤器,例如:
.filter(item -> !item.startsWith("a"))
...虽然这当然与问题无关。
【讨论】: