Is java Return Set null or Empty Set and Three Ways of Writing Empty Set

  • 2021-12-12 04:15:03
  • OfStack

Directory return collection is null or empty collection and three ways to write empty collection; Ways to return empty List 1: new ArrayList () Ways 2: new ArrayList (0) Ways 3: Collections. emptyList () (Recommended)

Return whether the set is null or an empty set and three ways to write an empty set

Personally, I think that when I write an interface, I need to return an empty set when I need to return a set. For example, if mybatis query returns a set, it will return an empty set instead of null when the result is empty.

So what are the benefits of this? The biggest advantage is that the caller does not have to decide whether it is null, but can use it directly, because there is no need to throw a null pointer.

Of course, this also has disadvantages, if you return Lists. newArrayList (); Or new ArrayList (); This creates a new object, which is probably unnecessary, wasting performance.

Of course, there are solutions, such as Collections. emptyList (); This method returns 1 empty collection, does not create a new object, but returns


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

This variable.

There's a downside to this, of course, if the caller just walks through it, there's nothing wrong with it, but if you want to add or delete elements inside it, there's an error.

Then you may wonder why, the reason is that when the call is written directly in the code, it will make an error, so why do you write it like this?

The reason is also very simple. If multiple threads add or delete this collection, the caller will be completely messed up, so the method of reporting errors directly and failing quickly is adopted

To solve the problem.

Summary:

Returns null, new ArrayList < > (), returning EMPTY_LIST.

null is definitely not recommended, so should we create a new List or return an empty List?

This depends on the performance requirements of the interface. If the performance requirements are high, return EMPTY_LIST, otherwise create a new object.

How to return an empty List

Mode 1: new ArrayList ()

JDK1.8 has been optimized, and the list created by the default constructor shares an empty array internally, which will be expanded to the default capacity when data is inserted for the first time;


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

Mode 2: 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);
}
}

Mode 3: Collections. emptyList () (Recommended)

Features: Immutable and safe


/**
* 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<String> 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;
}
}

Related articles: