我正在使用LinkedList
数据结构serverList
来存储元素。截至目前,它还可以在LinkedList null
中插入serverList
,这不是我想要的。是否有任何其他我可以使用的数据结构,它不会在serverList
列表中添加null元素但保持插入顺序?
public List<String> getServerNames(ProcessData dataHolder) {
// some code
String localIP = getLocalIP(localPath, clientId);
String localAddress = getLocalAddress(localPath, clientId);
// some code
List<String> serverList = new LinkedList<String>();
serverList.add(localIP);
if (ppFlag) {
serverList.add(localAddress);
}
if (etrFlag) {
for (String remotePath : holderPath) {
String remoteIP = getRemoteIP(remotePath, clientId);
String remoteAddress = getRemoteAddress(remotePath, clientId);
serverList.add(remoteIP);
if (ppFlag) {
serverList.add(remoteAddress);
}
}
}
return serverList;
}
此方法将返回一个List,我正在以正常方式在for循环中迭代它。如果一切都为null,我可以为空serverList
,而不是在列表中有四个空值。在上面的代码中,getLocalIP
,getLocalAddress
,getRemoteIP
和getRemoteAddress
可以返回null,然后它会在链接列表中添加null元素。我知道我可以添加if检查,但是如果在添加到Linked List之前检查四次,我需要添加。有没有更好的数据结构我可以在这里使用?
我有一个约束 - 这个库在非常繁重的负载下使用,所以这段代码必须很快,因为它会被多次调用。
答案 0 :(得分:3)
我正在使用LinkedList数据结构serverList来存储元素。
鉴于你的目标是速度,这很可能是错误的。 ArrayList
速度要快得多,除非您将其用作Queue
或类似内容。
我知道我可以添加if检查但是我需要添加,如果在添加到Linked List之前检查四次。有没有更好的数据结构我可以在这里使用?
一个集合默默地忽略 null
将是一个坏主意。它有时可能有用,而在其他时候则非常令人惊讶。而且,它违反了List.add
合同。 因此,您无法在任何严肃的图书馆中找到它并且您不应该实施它。
只需编写方法
void <E> addIfNotNullTo(Collection<E> collection, E e) {
if (e != null) {
collection.add(e);
}
}
并使用它。它不会让你的代码变得更短,但它会使它更清晰。
我有一个约束 - 这个库在非常繁重的负载下使用,所以这段代码必须很快,因为它会被多次调用。
请注意,与简单列表操作相比,任何IO 都要慢很多个数量级。
答案 1 :(得分:0)
使用Apache Commons Collection:
ListUtils.predicatedList(new ArrayList(), PredicateUtils.notNullPredicate());
向此列表添加null会抛出IllegalArgumentException。此外,您可以通过任何您喜欢的List实现来支持它,如果需要,您可以添加更多要检查的谓词。
一般来说,收藏品也相同。
答案 2 :(得分:0)
有些数据结构不允许使用null元素,例如ArrayDeque,但是这些将抛出异常而不是静默忽略null元素,因此您无需在插入之前检查null。
如果您在插入之前设置了无法添加空检查,则可以在返回之前迭代列表并删除空元素。
答案 3 :(得分:0)
最简单的方法是在LinkedList#add()
方法中覆盖getServerNames()
。
List<String> serverList = new LinkedList<String>() {
public boolean add(String item) {
if (item != null) {
super.add(item);
return true;
} else
return false;
}
};
serverList.add(null);
serverList.add("NotNULL");
System.out.println(serverList.size()); // prints 1
如果你看到自己在几个地方使用它,你可以把它变成一个类。
答案 4 :(得分:0)
您可以使用普通Java HashSet
来存储路径。 null
值可能会多次添加,但只会在Set
中出现一次。您可以从null
中删除Set
,然后在返回前转换为ArrayList
。
Set<String> serverSet = new HashSet<String>();
serverSet.add(localIP);
if (ppFlag) {
serverSet.add(localAddress);
}
if (etrFlag) {
for (String remotePath : holderPath) {
String remoteIP = getRemoteIP(remotePath, clientId);
String remoteAddress = getRemoteAddress(remotePath, clientId);
serverSet.add(remoteIP);
if (ppFlag) {
serverSet.add(remoteAddress);
}
}
}
serverSet.remove(null); // remove null from your set - no exception if null not present
List<String> serverList = new ArrayList<String>(serverSet);
return serverList;
答案 5 :(得分:0)
由于你使用了番石榴(标记了它),如果你能够返回Collection
而不是List
,我就有了这个选择。
为什么Collection
?因为List
强制您返回true
或抛出异常。 Collection
允许您返回false
,如果您没有添加任何内容。
class MyVeryOwnList<T> extends ForwardingCollection<T> { // Note: not ForwardingList
private final List<T> delegate = new LinkedList<>(); // Keep a linked list
@Override protected Collection<T> delegate() { return delegate; }
@Override public boolean add(T element) {
if (element == null) {
return false;
} else {
return delegate.add(element);
}
}
@Override public boolean addAll(Collection<? extends T> elements) {
return standardAddAll(elements);
}
}