Collections.singletonList/Collections.emptyList/Collections.emptyMap

最近在研究 Flutter pigeon 例子 的时候,发现如下实例代码:

import dev.flutter.pigeon.Pigeon.*;
import java.util.Collections;

public class StartActivity extends Activity {
  private class MyApi implements BookApi {
    List<Book> search(String keyword) {
      Book result = new Book();
      result.author = keyword;
      result.title = String.format("%s's Life", keyword);
      return Collections.singletonList(result)
    }
  }

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    BookApi.setup(getBinaryMessenger(), new MyApi());
  }
}

对其中的 Collections.singletonList(result) 比较感兴趣,研究了一下,发现还是比较有意义的。

Collections.singletonList()

这个方法主要用于只有一个元素的优化,减少内存分配,无需分配额外的内存,可以从SingletonList内部类看得出来,由于只有一个element,因此可以做到内存分配最小化,相比之下ArrayListDEFAULT_CAPACITY=10个。

    /**
     * Returns an immutable list containing only the specified object.
     * The returned list is serializable.
     *
     * @param  <T> the class of the objects in the list
     * @param o the sole object to be stored in the returned list.
     * @return an immutable list containing only the specified object.
     * @since 1.3
     */
    public static <T> List<T> singletonList(T o) {
        return new SingletonList<>(o);
    }

下面是SingletonList静态类的定义

    private static class SingletonList<E>
        extends AbstractList<E>
        implements RandomAccess, Serializable {
 
        private static final long serialVersionUID = 3093736618740652951L;
 
        private final E element;
 
        SingletonList(E obj)                {element = obj;}
 
        public Iterator<E> iterator() {
            return singletonIterator(element);
        }
 
        public int size()                   {return 1;}
 
        public boolean contains(Object obj) {return eq(obj, element);}
 
        public E get(int index) {
            if (index != 0)
              throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
            return element;
        }
 
        // Override default methods for Collection
        @Override
        public void forEach(Consumer<? super E> action) {
            action.accept(element);
        }
        @Override
        public boolean removeIf(Predicate<? super E> filter) {
            throw new UnsupportedOperationException();
        }
        @Override
        public void replaceAll(UnaryOperator<E> operator) {
            throw new UnsupportedOperationException();
        }
        @Override
        public void sort(Comparator<? super E> c) {
        }
        @Override
        public Spliterator<E> spliterator() {
            return singletonSpliterator(element);
        }
    }

上面的源码中可以看到,静态类中并没有重新add、delete、set等方法。所以通过Collections.singletonList初始化的List是不能执行上述方法的。

Collections.emptyList()

Collections.emptyList在日常开发中也比较常用,如果一个方法需要返回一个空List,并且后续不用再新增元素进去,我们完全可以直接返回Collections.emptyList()而不是new ArrayList;这样不用每次都去创建一个新对象。

    public static final <T> List<T> emptyList() {
        return (List<T>) EMPTY_LIST;
    }

EMPTY_LIST如下

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

Collections中其他类似方法

public static <T> Set<T> singleton(T o);
 
public static <T> List<T> singletonList(T o);
 
public static <K,V> Map<K,V> singletonMap(K key, V value);
 
// 或者直接调用常量 EMPTY_LIST
public static final <T> List<T> emptyList();
 
//或者直接调用常量 EMPTY_MAP
public static final <K,V> Map<K,V> emptyMap();
 
//或者直接调用常量 EMPTY_SET
public static final <T> Set<T> emptySet()

参考链接