是否存在空列表数据结构



我使用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, getRemoteIPgetRemoteAddress可以返回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);
  }
}

相关内容

  • 没有找到相关文章

最新更新