Помощник для удаления пустых ссылок в списке Java? - PullRequest
40 голосов
/ 06 августа 2009

С учетом следующего списка:

List<String> list = new ArrayList<String>();

list.add("s1");
list.add("s2");
list.add(null);
list.add("s3");
list.add(null);
list.add("s4");

Мне нужен вспомогательный класс, который удаляет нулевые ссылки. Что-то вроде:

SomeHelper.removeNullReference (список);

такой, что список содержит только "s1", "s2", "s4", "s4" (ненулевые ссылки).

Что я должен использовать, чтобы выполнить это требование?

Ответы [ 6 ]

110 голосов
/ 06 августа 2009
list.removeAll(Collections.singleton(null));
9 голосов
/ 26 марта 2016

Java 8 добавил Collection.removeIf(Predicate), который удаляет все элементы, соответствующие предикату, поэтому вы можете удалить все вхождения null из списка (или любой коллекции) с помощью

list.removeIf(Objects::isNull);

с использованием java.util.Objects.isNull в качестве Predicate.

Вы также можете использовать .removeIf(x -> x == null), если хотите; разница очень мала .

3 голосов
/ 14 мая 2013

Недостатком подхода Дона является то, что он простирается от ArrayList. Пока это может быть достаточно, но что произойдет, если вы захотите использовать другую реализацию List? Вы можете создать NoNullsLinkedList и NoNullsCopyOnWriteArrayList и т. Д., Но затем вы получите кучу маленьких классов, которые отличаются только по своему предложению extends. Возможно, лучше создать оболочку List, которая не принимает нулевые значения. Например:

public class NonNullList<E> extends AbstractList<E> {
  private final List<E> delegate;

  public NonNullList(List<E> delegate) {
    this.delegate = delegate;
  }

  @Override
  public E get(int index) {
    return delegate.get( index );
  }

  @Override
  public int size() {
    return delegate.size();
  }

  @Override
  public E set(int index, E element) {
    return delegate.set( index, element );
  }

  @Override
  public void add(int index, E element) {
    if( element != null ) {
      delegate.add( index, element );
    }
  }

  @Override
  public E remove(int index) {
    return delegate.remove( index );
  }
}

Это больше кода, но теперь у вас есть возможность выбора реализации List при создании объекта.

Возможная проблема заключается в том, что вы все еще можете вставить null s в базовый объект List. Подход Дона не имеет такого же ограничения.

3 голосов
/ 15 августа 2011

Если вы можете управлять созданием List, вы можете предотвратить добавление нулей, написав собственную реализацию List, такую ​​как:

public class NoNullsList<E> extends ArrayList<E> {

  public void add(int index, E element) {
    if (element != null) {
      super.add(index, element);
    }
  }

  public boolean add(E e) {
    return e == null ? false : super.add(e);
  }
}

AFAIK, вам не нужно переопределять addAll, потому что его реализация ArrayList вызывает add.

List<String> list = new NoNullsList<String>();

list.add("s1");
list.add("s2");
list.add(null);
list.add("s3");
list.add(null);
list.add("s4");
1 голос
/ 26 марта 2016

Мне действительно нравится новое краткое решение Java 8, я считаю, что вы должны использовать его, когда это возможно.

list.removeIf(Objects::isNull);

С другой стороны, если вы ищете простую реализацию, чтобы узнать, как это можно сделать, например, вспомогательный класс, который возвращает новый ненулевой список, вы можете взглянуть на следующий код. Это также может быть сделано для принятия универсальных типов, для простоты я использовал тот же тип коллекции (как в вопросе) в классе помощника.

package removenullrefdemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

class ListHelper {
    public static List<String> removeNullReference(List<String> list) {
        List<String> newList = new ArrayList<>();

        list.forEach(item -> {
            if (item != null)
                newList.add(item);
        });

        return newList;
    }
}

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();

        list.add("s1");
        list.add("s2");
        list.add(null);
        list.add("s3");
        list.add(null);
        list.add("s4");

        println("Items:");
        list.forEach(item -> println(item));

        // Remove null refs
        println("Items (after nulls removed):");
        boolean useJava8removeIf = false;
        if (useJava8removeIf) {
            println("Using Java8 removeIf method with predicate.");
            list.removeIf(Objects::isNull);
        }
        else {
            println("Using our own helper.");
            list = ListHelper.removeNullReference(list);
        }

        list.forEach(item -> println(item));

    }

    static void println(String msg) {
        System.out.println(msg);
    }
}
0 голосов
/ 03 июня 2013

удалить. Все не работает для меня. Вместо этого я создаю новый список:

new ArrayList<E>(list);

Просто так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...