for (int i = 0; i < list.size(); i++) {
list.get(i);
}
}
方案二,使用迭代器来获取集合元素?
private void traverse(List list) {
for (Iterator iterator = list.iterator(); iterator.hasNext()😉 {
iterator.next();
}
}
===============================================================
针对上述提出的2种方案,我们进行验证,因为我们开发中经常使用的List实现类是ArrayList和LinkedList。所以验证传入这2种集合类型时,验证集合遍历性能。
package com.nobody;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
-
@Description
-
@Author Mr.nobody
-
@Date 2021/4/25
-
@Version 1.0
*/
public class Demo {
public static void main(String[] args) {
// 集合大小
int ListSize = 200000;
// 初始化ArrayList集合
ArrayList arrayList = new ArrayList<>();
for (int i = 0; i < ListSize; i++) {
arrayList.add(i);
}
System.out.println(“ArrayList Type:”);
traverseWithFor(arrayList);
traverseWithIterator(arrayList);
// 初始化LinkedList集合
LinkedList linkedList = new LinkedList<>();
for (int i = 0; i < ListSize; i++) {
linkedList.add(i);
}
System.out.println(“LinkedList Type:”);
traverseWithFor(linkedList);
traverseWithIterator(linkedList);
}
private static void traverseWithFor(List list) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
System.out.println(“traverseWithFor:” + (System.currentTimeMillis() - startTime));
}
private static void traverseWithIterator(List list) {
long startTime = System.currentTimeMillis();
for (Iterator iterator = list.iterator(); iterator.hasNext()😉 {
iterator.next();
}
System.out.println(“traverseWithIterator:” + (System.currentTimeMillis() - startTime));
}
}
输出结果如下,发现集合类型是ArrayList时,使用for下标定位(方案一)遍历集合效率更高;集合类型是LinkedList时,使用迭代器(方案二)遍历集合效率更高。特别地,如果LinkedList集合量很大并且使用for下标遍历,效率极其差。
ArrayList Type:
traverseWithFor:9
traverseWithIterator:15
LinkedList Type:
traverseWithFor:35548
traverseWithIterator:12
==========================================================================
通过以上验证,发现不能单纯的使用其中一种方案来遍历传入的集合,因为传入参数的List的实现类是未知的。那我们可以判断传入参数的具体实现类,来决定使用哪种遍历算法不就可以了。
private static void traverse(List list) {
if (list instanceof ArrayList) {
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
} else if (list instanceof LinkedList) {
for (Iterator iterator = list.iterator(); iterator.hasNext()😉 {
iterator.next();
}
}
}
以上是比较理想化的情况,如果List的实现类随着时间,会增多或者减少,那岂不是要经常修改此方法,增加或者减少instanceof的条件判断?
所以在JDK1.4之后,出现了RandomAccess接口,它是一个空的标记接口。
package java.util;
public interface RandomAccess {
}
它的作用是,如果一个集合的实现类实现了此标记接口,表明此实现类支持快速随机访问(通常是固定时间)。RandomAccess 接口的主要目的是允许一般的算法能更改其行为,从而在随机或连续访问列表时能提供良好的性能。
通俗讲,就是在随机访问或者顺序遍历集合时候,我们可以根据集合实现类是否实现了RandomAccess接口,来决定使用不同的遍历策略。官方鼓励,对于那些遍历呈现线性访问时间,而且随机访问是固定时间的集合类,推荐实现RandomAccess接口。
例如ArrayList类实现了RandomAccess接口,LinkedList类是没有实现RandomAccess接口的。
官方也说明了,如果集合类实现了RandomAccess接口,推荐使用for (int i=0, n=list.size(); i < n; i++)遍历,避免使用Iterator迭代器遍历集合。反之,如果集合类是Sequence List(例如LinkedList),则推荐使用迭代器。
package com.nobody;
import java.util.*;
/**
-
@Description
-
@Author Mr.nobody
-
@Date 2021/4/25
-
@Version 1.0
*/
public class Demo {
public static void main(String[] args) {
// 集合大小
int ListSize = 200000;
// 初始化ArrayList集合
ArrayList arrayList = new ArrayList<>();
for (int i = 0; i < ListSize; i++) {
arrayList.add(i);
}
System.out.println(“ArrayList Type:”);
traverseWithFor(arrayList);
traverseWithIterator(arrayList);
traverse(arrayList);
LinkedList linkedList = new LinkedList<>();
for (int i = 0; i < ListSize; i++) {
linkedList.add(i);
}
System.out.println(“LinkedList Type:”);
traverseWithFor(linkedList);
traverseWithIterator(linkedList);
traverse(linkedList);
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
" style=“zoom: 33%;” />
总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
[外链图片转存中…(img-rnA9ap35-1713662850160)]
[外链图片转存中…(img-LVnmFu0x-1713662850160)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!