Collections.singletonList() && Collections.emptyList()

Collections.singletonList()

最开始我是把它当作只存一个对象的列表的快速构造,即

1
2
3
4
5
6
List<String> list = new ArrayList<>();
list.add("");
return list;

// 相比底下的一行代码实现,前者没那么优雅
Collections.singletonList("");

但是问题随之而来,singletonList构造的列表是一个不可变列表,万一后面业务要对该列表进行变动,就会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 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
*/
/**
* 返回仅包含指定对象的不可变列表。返回的列表是可序列化的。
* 参数:o ― 要存储在返回列表中的唯一对象。
* 返回:仅包含指定对象的不可变列表。
*/
public static <T> List<T> singletonList(T o) {
return new SingletonList<>(o);
}

所以singletonList一般不适用业务场景

不过如果是单纯的返回给前端,或者需要序列化,就可以用,因为序列化不会保留类型,只是简单地将数据还原为基本的 JSON 结构。

那么,如果不想用最开始的那三行代码,该怎么办呢

1
new ArrayList<>(Collections.singletonList(""));

不过这样子也挺丑的,先转成一个不可变数组,再拷贝一份,这样还会导致多余的空间浪费

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
/**
* 构造一个列表,其中包含指定集合的元素,按集合的迭代器返回的顺序排列。
* 参数:c – 其元素要放入此列表中的集合
* 抛出:NullPointerException – 如果指定的集合为 null
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}

所以,最好的方法还是那三行[doge]

Collections.emptyList()

其实这个的坑和上面的差不多,因为它返回的空列表也是一个不可变的,所以如果拿到列表的引用(指针),不能对其进行新增等操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 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
*/
/**
* 返回一个空列表(不可变)。此列表是可序列化的。
* 此示例说明了获取空列表的类型安全方法:
* List<String> s = Collections. emptyList();
*
* 返回:空的不可变列表
* 实现 注意:
* 此方法的实现不需要为每个调用创建单独的 List 对象。使用此方法的成本可能与使用同名字段的成本相当。(与此方法不同,该字段不提供类型安全)
*/
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}

枚举类

1
2
3
4
5
6
7
8
9
10
11
12
13
enum Color {
RED("Red Color"), GREEN("Green Color"), BLUE("Blue Color");

private final String name;

Color(String name) {
this.name = name;
}

public String getName() {
return this.name + "_theme";
}
}

name()

  • 来源: name() 是所有枚举类型内置的方法,由 Enum 类提供。
  • 作用: 返回该枚举常量的名称,即声明枚举时使用的名称(枚举常量的标识符)。
  • 不可修改: name() 返回的值是编译时确定的,不能被重写或改变。
  • 用法: 适用于希望获取枚举常量的准确名称(通常是大写字母)的场景。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Returns the name of this enum constant, exactly as declared in its
* enum declaration.
*
* <b>Most programmers should use the {@link #toString} method in
* preference to this one, as the toString method may return
* a more user-friendly name.</b> This method is designed primarily for
* use in specialized situations where correctness depends on getting the
* exact name, which will not vary from release to release.
*
* @return the name of this enum constant
*/
/**
* 返回此枚举常量的名称,与其枚举声明中声明的名称完全相同。 大多数程序员应该优先使用该方法 toString ,
* 而不是这种方法,因为 toString 方法可能会返回更用户友好的名称。 此方法主要用于正确性取决于获取确切名称的特殊情况,该名称不会因版本而异。
* 返回:此枚举常量的名称
*/
public final String name() {
return name;
}

Color color = Color.RED;
System.out.println(color.name()); // 输出: RED

getName()(自定义)

  • 自定义方法: 在枚举类中定义的一个方法,用来返回枚举常量的自定义名称或其他相关的字段值。
  • 灵活性: 可以返回枚举常量的别名或自定义属性,适用于需要更灵活或者自定义的表示的场景。
  • 可修改: 可以为枚举常量定义额外的字段(如 name)并通过 getName() 方法返回这些字段的值。
1
2
Color color = Color.RED;
System.out.println(color.getName()); // 输出: Red Color_theme