• java返回集合为null还是空集合以及空集合的三种写法


     

     

    个人认为在自己写接口时,需要返回集合时返回一个空集合,比如mybatis查询如果返回一个集合,结果为空时也会返回一个空集合而不是null。

    那么这样有什么好处呢?最大的好处就是调用方不用在判断是否为null,可以直接用,因为不用抛空指针。

    当然这也有缺点,如果返回Lists.newArrayList();或者new ArrayList();这会新建一个对象,而这个对象很可能是没必要的,这样白白浪费性能。

    解决方法当然也有,可以用Collections.emptyList();这个方法返回一个空集合,并不会新建对象,而是返回

    public static final List EMPTY_LIST = new EmptyList<>(); 

    这个变量。

    当然这也有缺点,如果调用方只是遍历,这没什么不会报错,但是如果要新增,删除里面的元素那就会报错,

    那么你可能想为什么,原因就是代码里直接写死了调用时报错,那么为什么要这样写呢?

    原因也很简单,如果多个线程对这个集合增删,那么调用方就全乱了,所以采用了直接报错,快速失败的方法

    来解决问题。

    总结:

    返回null,返回new ArrayList<>(),返回EMPTY_LIST 。

    null肯定是不推荐的,那么是新建一个List还是返回空List呢?

    这要根据接口的性能要求,如果性能要求高返回EMPTY_LIST,否则新建一个对象。

    返回空List的方式

    方式一:new ArrayList()
     JDK1.8已经优化了,默认构造函数创建的list内部共享空数组,首次插入数据时才会扩容到默认容量;

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    方式二:new ArrayList(0)

    private static final Object[] EMPTY_ELEMENTDATA = {};
    public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
    this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
    this.elementData = EMPTY_ELEMENTDATA;
    } else {
    throw new IllegalArgumentException("Illegal Capacity: "+
    initialCapacity);
    }
    }



    方式三:Collections.emptyList()(推荐)
     特点:不可变,安全

    /**
    * The empty list (immutable). This list is serializable.
    *
    * @see #emptyList()
    */
    @SuppressWarnings("rawtypes")
    public static final List EMPTY_LIST = new EmptyList<>();
    
    /**
    * Returns an empty list (immutable). This list is serializable.
    *
    * <p>This example illustrates the type-safe way to obtain an empty list:
    * <pre>
    * List&lt;String&gt; s = Collections.emptyList();
    * </pre>
    *
    * @implNote
    * Implementations of this method need not create a separate <tt>List</tt>
    * object for each call. Using this method is likely to have comparable
    * cost to using the like-named field. (Unlike this method, the field does
    * not provide type safety.)
    *
    * @param <T> type of elements, if there were any, in the list
    * @return an empty immutable list
    *
    * @see #EMPTY_LIST
    * @since 1.5
    */
    @SuppressWarnings("unchecked")
    public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
    }
    
    /**
    * @serial include
    */
    private static class EmptyList<E>
    extends AbstractList<E>
    implements RandomAccess, Serializable {
    private static final long serialVersionUID = 8842843931221139166L;
    
    public Iterator<E> iterator() {
    return emptyIterator();
    }
    public ListIterator<E> listIterator() {
    return emptyListIterator();
    }
    
    public int size() {return 0;}
    public boolean isEmpty() {return true;}
    
    public boolean contains(Object obj) {return false;}
    public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
    
    public Object[] toArray() { return new Object[0]; }
    
    public <T> T[] toArray(T[] a) {
    if (a.length > 0)
    a[0] = null;
    return a;
    }
    
    public E get(int index) {
    throw new IndexOutOfBoundsException("Index: "+index);
    }
    
    public boolean equals(Object o) {
    return (o instanceof List) && ((List<?>)o).isEmpty();
    }
    
    public int hashCode() { return 1; }
    
    @Override
    public boolean removeIf(Predicate<? super E> filter) {
    Objects.requireNonNull(filter);
    return false;
    }
    @Override
    public void replaceAll(UnaryOperator<E> operator) {
    Objects.requireNonNull(operator);
    }
    @Override
    public void sort(Comparator<? super E> c) {
    }
    
    // Override default methods in Collection
    @Override
    public void forEach(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    }
    
    @Override
    public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
    
    // Preserves singleton property
    private Object readResolve() {
    return EMPTY_LIST;
    }
    }



  • 相关阅读:
    模板
    洛谷
    Codeforces
    Codeforces
    Codeforces
    Codeforces
    洛谷
    洛谷
    洛谷
    NOIP 普及组 2016 海港
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/15015569.html
Copyright © 2020-2023  润新知