LinkedList.pollLast () генерирует исключение NullPointerException - PullRequest
0 голосов
/ 21 апреля 2011

Я использую Java 6 Collecetions 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:

Извлекает и удаляет последний элемент этого спискаили возвращает ноль, если этот список пуст.

Также добавляется синхронизация добавления элементов.

Кто-нибудь знает, что может быть причиной исключения?

Спасибо залюбые идеи

Ответы [ 3 ]

3 голосов
/ 21 апреля 2011

Я полагаю, что сикронизация выполнена не на том объекте! Это должно быть dq, но не o!

... synchronized (dg) { ...
1 голос
/ 21 апреля 2011

Я запустил добавление вашего кода, используя следующий тест

    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)
0 голосов
/ 21 апреля 2011

см. этот Javadoc он говорит

 Removes and returns the last element from this list.

сначала он удаляет объект, поэтому, если он равен нулю, генерируется исключение NullPointerException:

так что сделайте метод add (..) синхронизированным и проверьте размер до dq.pollLast();

...