Collections.singletonList(something)
是不可变的,
对Collections.singletonList(something)
返回的列表所做的任何更改将导致UnsupportedOperationException
。
Arrays.asList(something)
允许Arrays.asList(something)
更改 。
此外,由Collections.singletonList(something)
返回的List的容量将始终为1,
而Arrays.asList(something)
的容量将为已支持数组的大小。
* 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);}/*** @serial include*/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@Overridepublic void forEach(Consumer<? super E> action) {action.accept(element);}@Overridepublic boolean removeIf(Predicate<? super E> filter) {throw new UnsupportedOperationException();}@Overridepublic void replaceAll(UnaryOperator<E> operator) {throw new UnsupportedOperationException();}@Overridepublic void sort(Comparator<? super E> c) {}@Overridepublic Spliterator<E> spliterator() {return singletonSpliterator(element);}}
附录:
package com.ysyc.invoicecertify.util.mockservice;import java.util.Arrays;
import java.util.List;/**** 本类演示了Arrays类中的asList方法* 通过四个段落来演示,体现出了该方法的相关特性.** (1) 该方法对于基本数据类型的数组支持并不好,当数组是基本数据类型时不建议使用* (2) 当使用asList()方法时,数组就和列表链接在一起了.* 当更新其中之一时,另一个将自动获得更新。* 注意:仅仅针对对象数组类型,基本数据类型数组不具备该特性* (3) asList得到的数组是的没有add和remove方法的** 通过查看Arrays类的源码可以知道,asList返回的List是Array中的实现的* 内部类,而该类并没有定义add和remove方法.另外,为什么修改其中一个,另一个也自动* 获得更新了,因为asList获得List实际引用的就是数组*/
public class AsListTest {public static void main(String[] args) {/* 段落一:基本数据类型使用asList中的问题 *//* 说明:虽然在JDK1.6中能够将基本数据类型的数组转换成List,但还是有个缺陷 */int[] a_int = { 1, 2, 3, 4 };/* 预期输出应该是1,2,3,4,但实际上输出的仅仅是一个引用, 这里它把a_int当成了一个元素 */List a_int_List = Arrays.asList(a_int);foreach(a_int_List);/* 为此我们需要这样遍历其中元素 */foreachForBase(a_int_List);System.out.println("1 END 2 START");/* 段落二:对象类型的数组使用asList,是我们预期的 */Integer[] a_Integer = new Integer[] { 1, 2, 3, 4 };List a_Integer_List = Arrays.asList(a_Integer);foreach(a_Integer_List);System.out.println("2 END 3 START");/* 段落三:当更新数组或者asList之后的List,另一个将自动获得更新 */a_Integer_List.set(0, 0);foreach(a_Integer_List);foreach(a_Integer);System.out.println("3 END 4 START");a_Integer[0] = 5;foreach(a_Integer_List);foreach(a_Integer);/* 段落四:对基本类型数组,通过asList之后的List修改对应的值后,在运行时会报出异常* 但是基本类型数组对应的List是会发生变化的,这是毫无疑问的*/a_int_List.set(0, 0);foreach(a_int_List);foreach(a_int);System.out.println("4 END 5 START");a_int[0] = 5;foreachForBase(a_int_List);foreach(a_int);}/* 打印方法 */private static void foreach(List list) {for (Object object : list) {System.out.print(object + " ");}System.out.println();}private static void foreachForBase(List a_int_List) {int[] _a_int = (int[]) a_int_List.get(0);foreach(_a_int);}private static void foreach(int[] a_int) {for (int i : a_int) {System.out.print(i + " ");}System.out.println();}private static void foreach(Integer[] _a_Integer) {for (int i : _a_Integer) {System.out.print(i + " ");}System.out.println();}
}
结果:
Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integerat java.util.Arrays$ArrayList.set(Arrays.java:3847)at com.ysyc.invoicecertify.util.mockservice.AsListTest.main(AsListTest.java:56)
[I@762efe5d
1 2 3 4
1 END 2 START
1 2 3 4
2 END 3 START
0 2 3 4
0 2 3 4
3 END 4 START
5 2 3 4
5 2 3 4
Disconnected from the target VM, address: '127.0.0.1:54490', transport: 'socket'Process finished with exit code 1
Collections.singletonList方法的使用
方法注释
/*** 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*/
应用
这个方法主要用于只有一个元素的优化,减少内存分配,无需分配额外的内存,可以从SingletonList内部类看得出来,由于只有一个element,因此可以做到内存分配最小化,相比之下ArrayList的DEFAULT_CAPACITY=10个。
//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@Overridepublic void forEach(Consumer<? super E> action) {action.accept(element);}@Overridepublic boolean removeIf(Predicate<? super E> filter) {throw new UnsupportedOperationException();}@Overridepublic void replaceAll(UnaryOperator<E> operator) {throw new UnsupportedOperationException();}@Overridepublic void sort(Comparator<? super E> c) {}@Overridepublic Spliterator<E> spliterator() {return singletonSpliterator(element);}}
//普通写法List<MyBean> beans= MyService.getInstance().queryBean(param);if (CollectionUtils.isEmpty(beans)) {beans= new ArrayList<>();MyBean bean= new MyBean(param);beans.add(bean);}
//优化写法List<MyBean> beans= MyService.getInstance().queryBean(param);if (CollectionUtils.isEmpty(beans)) {MyBean bean= new MyBean(param);beans= Collections.singletonList(bean);}
其他特殊容器类
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()
- 需要注意的是,以上6个方法返回的容器类均是immutable,即只读的,如果调用修改接口,将会抛出UnsupportedOperationException
Collections.singletonList返回只有一个元素的不可变的List,以及其他状态的特殊集合
Collections.singletonList,返回只有一个元素的集合,省内存,因为默认的List在JDK1.8之后初始化后add元素之后的size=10