你有没有想过为什么java.util.collections
类包括各种“空的
“类的方法,返回空集合和迭代器不空不变?这篇文章回答了这个问题。
为什么返回空集合和迭代器是不变的吗?
返回空集合和空的迭代器不可改变的(不变的),他们可以在多线程中的安全使用。
花不可变列表为空
这个收藏
类的各种“空的
“类方法还提供了一个有用的选择无效的
(和避免潜在的java.lang.nullpointerexception
从被扔)在一定的语境中。清单1给出了源代码,一个应用程序,演示了一个不变的空列表的好处。
清单1。空和非空列表
S花
S
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
class Flowers
{
private List<String> flowers;
Flowers()
{
flowers = Collections.emptyList();
}
Flowers(String... flowerNames)
{
flowers = new ArrayList<String>();
for (String flowerName: flowerNames)
flowers.add(flowerName);
}
@Override
public String toString()
{
return flowers.toString();
}
}
public class EmptyListDemo
{
public static void main(String[] args)
{
Flowers flowers = new Flowers();
System.out.println(flowers);
flowers = new Flowers("Rose", "Violet", "Marigold");
System.out.println(flowers);
}
}
公司应当在1花
类存储各种花卉的名称列表中。这个类提供了两个构造函数:一个noargument构造函数和构造函数的变量数java.lang.string
参数识别不同的花。
《noargument invokes构造函数<T>列表<T> emptylist()
初始化其私人花
场空java.util.list
属于字符串
——emptylist()
是一个通用的方法,编译器会推断返回类型及其内容。
如果你想知道需要emptylist()
,检查toString()
方法注意,此方法评价tostring()花。
。如果你不指定一个指向一个空列表<字符串>
到花
,花
将包含无效的
参考(此实例字段的默认值创建对象时),和NullPointerException
对象会被试图评估时tostring()花。
。
编译清单1如下:
emptylistdemo.java javac
为运行结果的应用:
java emptylistdemo
你应该遵守以下输出:
[ ]
[玫瑰、紫罗兰、金盏花]
emptylist()
的实现
emptylist()
实施返回(列表<T>)empty_list
,它返回单列表
对象分配给empty_list
在课堂场域收藏
类你可能会想工作empty_list
直接的,但是你如果你碰到一个unchecked警告消息,因为empty_list
被宣布为原型列表
,和混合原料和泛型类型导致了这样的消息。虽然你可以抑制的警告,你最好使用emptylist()
方法
待办任务不变的空的迭代器
大多数“空的
“方法返回空集合不变,但三种方法返回的迭代器不空:<T>枚举<T> emptyenumeration()
(经典迭代法),<?> < > emptyiterator T T(的)
,和<T<T>>listiterator emptylistiterator()
。清单2展示了一个永恒的空的迭代器的需要。
清单2。NullPointerException
因零参考todolist
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
class ToDo
{
private String task;
private String date;
ToDo(String task, String date)
{
this.task = task;
this.date = date;
}
@Override
public String toString()
{
return task + ": "+ date;
}
}
class ToDoList
{
private List<ToDo> todoList;
void add(ToDo todo)
{
if (todoList == null)
todoList = new ArrayList<>();
todoList.add(todo);
}
public Iterator<ToDo> iterator()
{
return todoList.iterator();
}
}
public class EmptyIteratorDemo
{
public static void main(String[] args)
{
ToDoList todoList = new ToDoList();
//todoList.add(new ToDo("Mow the lawn", "April 5, 10 AM"));
Iterator<ToDo> todos = todoList.iterator();
while (todos.hasNext())
System.out.println(todos.next());
}
}
清单2给出了待办事项
和todolist
课程描述任务个人和列表中的任务名称和日期方面的任务已经完成。todolist
的()
方法简单地初始化列表。不幸的是,这可能会导致被延迟初始化NullPointerException
目标
NullPointerException
出现时ToDoList。()
进入todolist
的()
方法执行todolist
包含null引用,因为()
没有被称为。编译清单2(javac emptyiteratordemo.java
)和运行程序(Java emptyiteratordemo
在下面的输出结果):
<trans data-src="Exception in thread " main="" java="" lang="" nullpointerexception="" at="" todolist="" iterator="" emptyiteratordemo="" java:37="" java:47="" data-dst="" 在“主要”java线程异常。lang.nullpointerexception="" "="" style="background: transparent;">在“主要”java线程异常。lang.nullpointerexception
在todolist。迭代器(emptyiteratordemo。java:37)
在emptyiteratordemo。主要(emptyiteratordemo java:47。
你可以避免异常uncommentingToDoList。()
打电话的main()
方法更好的是,你可以修改todolist
的()
返回调用结果的方法collections.emptyiterator(的)
什么时候todolist
包含null引用,如下:
public Iterator<ToDo> iterator()
{
return (todoList != null) ? todoList.iterator()
: Collections.emptyIterator();
}
在例子的其他想法
在这个例子中,它会更好地分配一个新的java.util.arraylist
对象的todolist
领域,如todolist列表> <私人所有
,和忘记emptyiterator()
和NullPointerException
。然而,你可能会遇到更实际的情况下,你需要用一个空的迭代方法。
结论
这个收藏
类的各种“空的
“类的方法可以帮助你写出更安全的代码,避免丢nullpointerexceptions
。他们还可以帮助你写出更精简的代码,因为你并不总是有空引用的测试。例如,清单1中的toString()
指定方法花tostring()返回
而不是指定的时间return (flowers != null) ? flowers.toString() : "";
。