0

我使用 Java 6 集合 API。我需要一个应该只有 N 个元素的集合。我的意思是,如果我添加新元素并且集合已经有 N 个元素,那么应该删除最后一个元素并在集合头部添加一个新元素。我有以下代码片段来做到这一点:

class A {

  int N = 100;
  Deque dq = new LinkedList();

  void add(Object o) {
    synchronized (o) { 
      if (dq.size() == N) {
        dq.pollLast();
      }
      dq.add(o);
    }
  }

  Deque getDq() {
    return new LinkedList(dq);
  }
}

类型 A 的对象可以同时访问多个用户以添加新元素。在实践中,我得到了 NullPointerException :

Caused by: java.lang.NullPointerException
   at java.util.LinkedList.remove(LinkedList.java:790)
   at java.util.LinkedList.removeLast(LinkedList.java:144)
   at java.util.LinkedList.pollLast(LinkedList.java:573)
   at A.add(A.java:9)

Deque.pollLast() 合约没有说明 NullPointerException:

检索并删除此列表的最后一个元素,如果此列表为空,则返回 null。

元素的添加也是同步的。

有谁知道异常原因可能是什么?

感谢您的任何想法

4

3 回答 3

3

我猜sycronization是在错误的对象上完成的!应该是dq但不是o

... synchronized (dg) { ...
于 2011-04-21T11:18:11.677 回答
1

我已经使用以下测试运行了您的代码添加

    A a = new A();
    for (int i = 0; i < 200; i++)
    {
        a.add(i);
    }
    System.out.println(a.dq);

这一切似乎都正常工作。您能否在获得 NPE 时提供有关应用程序状态的更多详细信息?您要添加的对象是什么?当时的 Dequeue 是什么状态?

另外,你提到

如果我添加新元素并且集合已经有 N 个元素,则应删除最后一个元素并在集合头部添加新元素

你的代码没有这样做。现在,它添加到集合的尾部。要将其添加到头部,请更改

dq.add(o)

dq.addFirst(o)
于 2011-04-21T11:24:05.660 回答
0

看到它说的这个javadoc

 Removes and returns the last element from this list.

首先它删除对象,所以如果它为空,则抛出 NullPointerException:

所以使 add(..) 方法同步并在之前检查大小dq.pollLast();

于 2011-04-21T11:15:32.893 回答