是否有空的空闲列表数据结构?

时间:2015-07-07 07:26:33

标签: java data-structures linked-list guava

我正在使用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,而不是在列表中有四个空值。在上面的代码中,getLocalIPgetLocalAddressgetRemoteIPgetRemoteAddress可以返回null,然后它会在链接列表中添加null元素。我知道我可以添加if检查,但是如果在添加到Linked List之前检查四次,我需要添加。有没有更好的数据结构我可以在这里使用?

我有一个约束 - 这个库在非常繁重的负载下使用,所以这段代码必须很快,因为它会被多次调用。

6 个答案:

答案 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);
  }
}