我使用LinkedList
数据结构serverList
来存储其中的元素。到目前为止,它还可以在LinkedList serverList
中插入null
,这不是我想要的。是否有任何其他的数据结构,我可以使用它不会在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循环中迭代它。如果一切都是空的,我可以有空serverList
,而不是在我的列表中有四个空值。在我上面的代码中,getLocalIP
, getLocalAddress
, getRemoteIP
和getRemoteAddress
可以返回null,然后它将在链表中添加null元素。我知道我可以添加if检查,但是在添加到链表之前,我需要添加if检查四次。这里有更好的数据结构吗?
我有一个约束是-这个库是在非常重的负载下使用的,所以这个代码必须很快,因为它将被多次调用
我使用LinkedList数据结构serverList来存储其中的元素。
考虑到你的目标是速度,这很可能是错误的。ArrayList
要快得多,除非你把它当作Queue
或类似的东西使用。
我知道我可以添加if检查,但是在添加到链表之前,我需要添加if检查四次。这里有更好的数据结构吗?
集合静默地忽略 null
s将是一个坏主意。它有时可能很有用,但有时却很令人惊讶。此外,它还违反了List.add
合同。所以你不会在任何正规的库中找到它,你不应该实现它。
写一个方法
void <E> addIfNotNullTo(Collection<E> collection, E e) {
if (e != null) {
collection.add(e);
}
}
并使用它。它不会让你的代码更短,但会让它更清晰。
我有一个约束是-这个库是在非常重的负载下使用的,所以这个代码必须很快,因为它将被多次调用。
请注意,任何IO 都比简单的列表操作慢许多个数量级。
使用Apache Commons Collection:
ListUtils.predicatedList(new ArrayList(), PredicateUtils.notNullPredicate());
将null添加到此列表将抛出IllegalArgumentException。此外,您可以通过任何您喜欢的List实现来支持它,如果需要,您可以添加更多要检查的谓词。
有一些数据结构不允许null元素,比如ArrayDeque,但是这些数据结构会抛出异常,而不是静默地忽略null元素,所以无论如何您必须在插入之前检查是否为空。
如果您坚决反对在插入之前添加null检查,那么您可以在列表中进行迭代,并在返回列表之前删除null元素。
最简单的方法就是在你的getServerNames()
方法中重写LinkedList#add()
。
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
如果你看到自己在几个地方使用这个,你可能可以把它变成一个类。
您可以使用普通的Java HashSet
来存储路径。null
值可以被添加多次,但它只会在Set
中出现一次。您可以从Set
中删除null
,然后在返回之前转换为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;
由于您使用Guava(它被标记),如果您能够返回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);
}
}