我正在查看Collections类的源代码。我偶然发现了方法集合。synchronizedList(list)
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
我不明白为什么我们要检查list是否是RAnywhere Access类型。我知道ArrayList实现了这个接口,而LinkedList没有。
此外,SynchronizedRandomAccessList继承SynchronizedList。那么这张支票的意义是什么?请解释一下
您必须回想一下随机访问
标记接口的最初目的。如果您将List
传递给另一个方法,它应该能够选择一种适合随机访问或顺序列表的算法。选择正确的算法需要通过list instanceof随机访问
对标记接口进行测试。
举个例子
public static <T>
int binarySearch(List<? extends Comparable<? super T>> list, T key) {
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key);
else
return Collections.iteratorBinarySearch(list, key);
}
(另请参见反向、无序、复制和填充)
现在,如果您只是将列表包装到实现List
接口的另一个对象中,所有此类方法都看到是包装器对象,因此此信息会丢失。但是,像同步列表这样的包装器不会改变get
等随机访问方法的时间复杂度。因此,如果包装的列表是随机访问列表,则希望包装器也应该实现随机访问
,以便接收此类包装器的方法仍然能够检测快速随机访问是否可用。
如果你看一下同步随机访问列表(SynchronizedRandomAccessList)的实现,你会发现它所做的一切,就是扩展同步列表(SynchronizedList)并实现随机访问(RandomAccess),以继承行为并将自身标记为具有快速随机访问。它覆盖的唯一方法是子列表,原因完全相同。如果列表具有有效的随机访问,则其子列表也具有有效的随机访问,因此它们也应该实现随机访问。
static class SynchronizedRandomAccessList<E>
extends SynchronizedList<E>
implements RandomAccess {
SynchronizedRandomAccessList(List<E> list) {
super(list);
}
SynchronizedRandomAccessList(List<E> list, Object mutex) {
super(list, mutex);
}
public List<E> subList(int fromIndex, int toIndex) {
synchronized (mutex) {
return new SynchronizedRandomAccessList<>(
list.subList(fromIndex, toIndex), mutex);
}
}
请注意,其他包装工厂(如check edList
)遵循相同的模式。因此,这甚至在组合工厂时也有效:
System.out.println(
Collections.synchronizedList(Collections.checkedList(new ArrayList<>(), String.class))
instanceof RandomAccess);
→ 真的
System.out.println(
Collections.synchronizedList(Collections.checkedList(new LinkedList<>(), String.class))
instanceof RandomAccess);
→ 假
你就快到了<代码>集合。synchronizedList(list)检查随机访问,因为一些列表实现了随机访问,而其他列表则没有。
这是一个标记接口,就像可序列化的一样。它告诉我们是否可以随机访问列表中的项目。一、 e.从数组列表中,我们可以以相同的计算成本检索任何项。另一方面,我们需要遍历一个链接列表(LinkedList),以获得第n个元素。
那么,集合中发生了什么。synchronizedList(列表)
?它将随机访问列表包装成同步列表,而将非随机访问列表包装成非随机访问同步列表。否则,这些列表是相同的。下面是同步随机访问列表的代码。这是一个很好的差分编程示例。这两个类几乎相同。
static class SynchronizedRandomAccessList<E>
extends SynchronizedList<E>
implements RandomAccess {
SynchronizedRandomAccessList(List<E> list) {
super(list);
}
SynchronizedRandomAccessList(List<E> list, Object mutex) {
super(list, mutex);
}
public List<E> subList(int fromIndex, int toIndex) {
synchronized (mutex) {
return new SynchronizedRandomAccessList<>(
list.subList(fromIndex, toIndex), mutex);
}
}
private static final long serialVersionUID = 1530674583602358482L;
/**
* Allows instances to be deserialized in pre-1.4 JREs (which do
* not have SynchronizedRandomAccessList). SynchronizedList has
* a readResolve method that inverts this transformation upon
* deserialization.
*/
private Object writeReplace() {
return new SynchronizedList<>(list);
}
}
你可能会问,RandomAccess界面有什么意义?正如霍尔格指出的那样,<代码>集合。binarySearch()基于此接口做出决策。另一个例子是Collections.reverse()。
Spring留档指出: “如果最后两段代码实际上存在于同一个应用程序中,那么可以删除两个RowMapper匿名内部类中存在的重复,并将其提取到单个类(通常是静态内部类)中,然后根据需要由DAO方法引用。” 本例中的“最后两个片段”是使用两个具有相同逻辑的行映射器映射其调用结果的数据库方法。 我的问题是为什么内部RowMapper类需要是静态的。。。还是一定要这样?我的DAO中有一个自动连接的服务方
在中使用会在中创建一个奇怪的空白空间(如底部填充),导致不必要的滚动,因为没有更多的元素要显示。 这个填充随着而增长,我的意思是: 如果在中有0到2个元素,这非常适合屏幕,并且没有滚动。这里工作得很好。 如果在< code > recycle view 中有3到5个元素,这些元素会继续显示在屏幕上,但在这种情况下,会有更多的空白空间,从而导致不必要的滚动。 随着元素的增多,空白区域不断扩大,并创建
我对java.util.HashMap的概念理解如下:
我是个新手,一直在浏览源代码,发现: 这个函数定义这样的内部函数有什么原因吗?为什么不直接写:
问题内容: Python的内部/嵌套类使我感到困惑。没有他们,有什么事情是无法完成的吗?如果是这样,那是什么东西? 问题答案: 引用自http://www.geekinterview.com/question_details/64739: 内部类的优点: 类的逻辑分组 :如果一个类仅对另一个类有用,那么将其嵌入该类并将两者保持在一起是合乎逻辑的。嵌套此类“帮助程序类”可使它们的程序包更加简化。 增
本文向大家介绍lucence内部结构是什么?相关面试题,主要包含被问及lucence内部结构是什么?时的应答技巧和注意事项,需要的朋友参考一下 面试官:想了解你的知识面的广度和深度。 解答: Lucene是有索引和搜索的两个过程,包含索引创建,索引,搜索三个要点。可以基于这个脉络展开一些。