先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
正文
HashMap:底层是哈希表。
Hashtable:底层也是哈希表,只不过线程安全的,效率较低,使用较少。
Properties:是线程安全的,并且 key 和 value 只能存储字符串 String。
TreeMap:底层是二叉树。TreeMap集合的 key 可以自动按照大小顺序排序。
四、总结集合
List 集合存储元素的特点:
有序可重复
有序:存进去的顺序和取出的顺序相同,每一个元素都有下标。
可重复:存进去 1,可以再存储一个 1。
Set (Map)集合存储元素的特点:
无序不可重复
无序:存进去的顺序和取出的顺序不一定相同。另外 Set 集合中元素没有下标。
不可重复:存进去1,不能再存储 1了。
SortedSet (SortedMap)集合存储元素特点:
首先是无序不可重复的,但是 SortedSet 集合中的元素是可排序的。
无序:存进去的顺序和取出的顺序不一定相同。另外 Set 集合中元素没有下标。
不可重复:存进去1,不能再存储 1了。
可排序:可以按照大小顺序排列。
Map 集合的 key,就是一个 Set 集合。往 Set 集合中放数据,实际上放到了 Map 集合的 key 部分。
五、关于集合遍历/迭代专题
下面将放上代码来进行演示迭代器的大致使用方法
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Collection01 {
public static void main(String[] args) {
// 注意:以下讲解的遍历方式/迭代方式,是所有CoLLection通用的一种方式。
// 在Map集合中不能用。在所有的CoLLection以及子类中使用。
// 创建集合对象
Collection c = new ArrayList(); // 后面的集合无所谓,主要是看前面的Collection接口,怎么遍历/迭代。
//添加元素
c.add(123);
c.add(1.34);
c.add("你好");
c.add(new Object());
// 集合Collection进行遍历/迭代
// 第一步: 获取集合象的送代器Iterator
Iterator it = c.iterator();
// 第二步: 通过以上获取的迭代器对象开始迭代/遍历集合。
/*以下两个方法是迭代器对象Iterator中的方法
boolean hasNext()如果仍有元素可以迭代,则返回 true。
Object next() 返回迭代的下一个元素。*/
while(it.hasNext()){
System.out.println(it.hasNext());
Object obj = it.next();
System.out.println(obj);
}
}
}
如果new 的是HashSet对象,则输出的内容会是无序不可重复的
package Dome;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Collection01 {
public static void main(String[] args) {
// 创建HashSet集合对象:无序不可重复
Collection c = new HashSet(); // 后面的集合无所谓,主要是看前面的Collection接口,怎么遍历/迭代。
//无序:存进去的顺序和取出来的顺序不一定相同。
//不可重复:存储了100,就不能再存储一个100
c.add(123);
c.add(777);
c.add(100);
c.add(6987);
c.add(35435);
c.add(100);
//获取迭代器进行迭代
Iterator it = c.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(obj); /*100、777、123、6987、35435。可以看到添加了两个100最后只输出了一个100,验证了不可重复性。输出的顺序没有规律可循,则验证了无序性。
}
}
}
1、contains方法深入解析
boolean contains(Object o)
作用:判断集合中是否包含某个对象o,如果包含返回true ,如果不包含返回false。
contains方法是用来判断集合中是否包含某个元素的方法,那么在底层是怎么判断集合中是否包含某个元素的呢 ?
在底层contains方法调用了equals方法进行比对。equals方法返回true,就表示包含这个元素。
通过以下代码判断c集合中是否包含x?程序输出的结果为true还是false
import java.util.ArrayList;
import java.util.Collection;
public class Collection01 {
public static void main(String[] args) {
//创建集合对象
Collection c = new ArrayList();
//向集合中添加元素
String s1 = new String("abc");
c.add(s1);
String s2 = new String("qwe");
c.add(s2);
//创建新对象String
String x = new String("abc");
//c集合中是否包含x?猜测一下结果是否为true还是false?
System.out.println(c.contains(x));//判断集合中是否存在"abc"
}
}
结论: 存放在一个集合中的类型,一定要重写equals方法
注意:当集合的结果发生改变之后,迭代器必须重新获取。
2、集合元素的remove
**重点:**当集合的结构发生改变时,送代器必须重新获取,如果还是用以前老的迭代器,会出现
异常:java.util.ConcurrentModificationException
当我们使用 引用“ . ”remove方法删除了元素后,此时集合的结构发生了改变,会出现异常错误,需要重新获取迭代器。
出异常根本原因是:集合中元素删除了,但是没有更新送代器(送代器不知道集合变化了)
如果不重新获取迭代器,可以使用迭代器来进行删除。
送代器去删除时,会自动更新送代器,并且更新集合(删除集合中的元素)。
示例代码:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Collection01 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(123);
c.add(435);
c.add(1.23);
Iterator it = c.iterator();
while (it.hasNext()){
System.out.println(it.next());
it.remove(); // 删除的一定是送代器指向的当前元素
}
System.out.println(c.size());
}
}
总结:
重点:当集合的结构发生改变时,送代器必须重新获取,如果还是用以前老的送代器,会出现异常:java.util.ConcurrentModificationException 重点:在送代集合元素的过程中,不能调用集合对象的remove方法,删除元素:c.remove(o); 送代过程中不能这样。 会出现 :java.util.ConcurrentModificationException 重点:在送代元素的过程当中,一定要使用送代器Iterator的remove方法,删除元素不要使用集合自带的remove 方法删除元素。
3、List接口的常用方法
3.1、List集合存储元素特点:有序可重复
有序:List集合中的元素有下标。
从0开始,以1递增。
可重复:存储一个1,还可以再存储1。
3.2、List既然是Collection接口的子接口,那么肯定List接口有自己“特色”的方法:
以下只列出List接口特有的常用的方法:
在指定的索引位置插入一个元素:void add(int index, E element)
获取指定索引位置的元素 :E get(int index)
查找指定对象第一次出现的索引位置: int indexOf(Object o)
查找指定对象最后一次出现的索引位置:int lastIndexOf(Object o)
删除指定索引的元素:E remove(int index )
指定索引位置的元素替换为新的元素 :E set(int index, E element)
4、ArrayList集合
1、默认初始化容量10(底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量10。)
2、集合底层是一个object[]数组。
3、构造方法:
new ArrayList();
new ArrayList(20);
示例代码:
import java.util.ArrayList;
import java.util.List;
public class Collection01 {
public static void main(String[] args) {
// 默认初始化容量是10
// 数组的长度是10
List list = new ArrayList();
//集合的size()方法是获取当前集合中元素的个数。不是获取集合的容量
System.out.println(list.size()); // 0
// 指定初始化容量
// 数组的长度是20
List list1 = new ArrayList(20);
// 集合的size()方法是获取当前集合中元素的个数。不是获取集合的容量
System.out.println(list1.size()); //0
}
}
4、ArrayList集合的扩容:
增长到原容量的1.5倍。
ArrayList集合底层是数组,怎么优化?
尽可能少的扩容。因为数组扩容效率比较低,建议在使用ArrayList集和的时候预估计元素的个数,给定一个初始化容量。
5、数组优点:
检索效率比较高。(每个元素占用空间大小相同,内存地址是连续的,知道首元素内存地址,然后知道下标,通过数学表达式计算出元素的内存地址,所以检索效率最高。)
6、数组缺点:
随机增删元素效率比较低。
另外数组无法存储大数据量。(很难找到一块非常巨大的连续的内存空间。)
7、向数组末尾添加元素,效率很高,不受影响。
8、面试官经常问的一个问题 ?
这么多的集合中,你用哪个集合最多?
答:ArrayList集合。
9、ArrayList集合是非线程安全的。(不是线程安全的集合。)
HashSet集合转挽成List集合
10、ArrayList: 把检索发挥到极致。(未尾添加元素率还是高的)。
LinkedList: 把随机增删发挥到极致。
加元素都是往未尾添加,所以ArrayList用的比LinkedList多。
示例代码:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
public class Collection01 {
public static void main(String[] args) {
// 创建一个Hashset集合
Collection c = new HashSet();
c.add(100);
c.add(200);
c.add(900);
c.add(50);
// 通过这个构造方法就可以HashSet集合转挽成List集合。
List mylist2 = new ArrayList(c);
for(int i = 0; i < mylist2.size(); i++){
System.out.println(mylist2.get(i));
}
}
}
5、vector
01、底层也是一个数组。
02、初始化容量:10
03、怎么扩容的?
扩容之后是原容量的2倍,10–>20–>40–> 80
04、ArrayList集合扩容特点:
ArrayList集合扩容是原容量1.5倍
05、Vector中所有的方法都是线程同步的,都带有synchronized关健字是线程安全的。效率比较低,使用较少了
使用示例代码:
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
public class LinkList {
public static void main(String[] args) {
//创建一个Vector集合
List vector = new Vector();
//添加元素
vector.add(123);
vector.add(3.14);
vector.add("你好");
Iterator it = vector.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
六、泛型
01、自JDK5之后就有了泛型机制
02、用泛型来指定集合中存储的数据类型。
03、在使用了泛型机制之后,表示某集合中只允许存储自定义的数据类型
04、泛型这种语法机制,只在程序编译阶段起作用,只是给编译器参考的。(运行阶段泛型没用!)
05、使用了泛型好处是什么?
第一:集合中存储的元素类型统一了。
第二:从集合中取出的元素类型是泛型指定的类型,不需要进行大量的“向下转型”!
06、泛型的缺点是什么?
导致集合中存储的元素缺乏多样性!
使用代码示例:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class MyList {
public static void main(String[] args) {
//指定List集合中只能存储Animal,那么存储string 就编译报错了。
//这样用了泛型之后,集合中元素的数据类型更加统一了。
List<Animal> list = new ArrayList<Animal>();
Cat cat = new Cat();
Bird bird = new Bird();
list.add(cat);
list.add(bird);
//获取迭代器
//表示这个迭代器中存储的是Animal类型的数据
Iterator<Animal> it = list.iterator();
while(it.hasNext()){
// 使用泛型之后,每一次跌代返回的数据都是Animal类型
Animal a = it.next();
if (a instanceof Cat){
Cat newcat = (Cat)a;
newcat.Move();
}
if (a instanceof Bird){
Bird newBird = (Bird)a;
newBird.Sing();
}
}
}
}
class Animal{
public void Name(){
System.out.println("这里是所有的动物");
}
}
class Bird extends Animal{
public void Sing(){
System.out.println("鸟儿在歌唱");
}
}
class Cat extends Animal{
public void Move(){
System.out.println("猫在走猫步");
}
}
我们还可以自定义泛型:自定义泛型的时候,<>尖括号中的是一个标识符,随便写。java源代码中经常出现的是:
和
E是Element单词首字母。
T是Type单词首字母。
七、增强for循环( foreach)
语法格式:
for(元素类型 变量名 : 数组或集合){
System.out.println(变量名);
}
这种方式效率比较高,因为获取key和value 都是直接从node对象中获取的属性值
这种方式比较适合于大数据量。
foreach有一个缺点:没有下标。在需要使用下标的循环中,不建议使用增强for循环。
使用代码示例:
public class MyList{
public static void main(String[] args) {
//创建一个String类型的数组
String arr[] = {"123", "456", "789"};
for(String s : arr){
System.out.println(s);
}
}
}
八、Map接口
java.util.Map接口中常用的方法 :
1、Map和Collection 没有继承关系。
2、Map集合以key和value的方式存储数据:键值对
key和value都是引用数据类型。
key和value都是存储对象的内存地址。
key起到主导的地位,value是key的一个附属品。
3、Map接口中常用方法:
V put(K key,V value) 向Map集合中添加键值对
V get(Object key) 通过key获取value
void clear() 清空Map集合
boolean containsKey(Object key) 判断Map中是否包含某个key
boolean containsValue(Object value) 判断Map中是否包含某个value
boolean isEmpty() 判断Map集合中元素个数是否为0
Set keySet() 获取Map集合所有的key(所有的键是一个set集合)
V remove(Object key) 通过key删除键值对
int size() 获Map集合中键值对的个数。
Collection values() 获Map集合中所有的value,返回一个Collection
Set<Map.Entry<K,V>> entrySet() 将Map集合转换成Set集合
注意 : Map集合通过entrySet()方法转换成的这Set集合,Set集合中元素的类型是Map. Entry<K, V>
Map.Entry和String一样,都是一种类型的名字,只不过:Map.Entry是静态内部类,是Map中的静态内部类
假设现在有一个Map集合,如下所示 :
key | value |
---|---|
1 | zhangsan |
2 | lisi |
3 | wangwu |
4 | zhaoliu |
01、V put(K key,V value) 向Map集合中添加键值对
示例代码:
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
}
}
02、V get(Object key) 通过key获取value
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//通过key获取value
String value2 = map.get(2);
System.out.println(value2);
}
}
03、int size() 获Map集合中键值对的个数。
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//获Map集合中键值对的个数。
int Num = map.size();
System.out.println(Num); //4
}
}
04、V remove(Object key) 通过key删除键值对
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//通过key删除键值对
map.remove(2);
//获取集合中键值对的个数
System.out.println(map.size()); //3
}
}
05、boolean containsKey(Object key) 判断Map中是否包含某个key
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//判断Map中是否包含某个key
boolean b = map.containsKey(2);
System.out.println(b); //true
}
}
06、boolean containsValue(Object value) 判断Map中是否包含某个value
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//判断Map中是否包含某个Value
boolean b = map.containsValue("zhangsan");
System.out.println(b); //true
}
}
07、Collection values() 获Map集合中所有的value,返回一个Collection
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//获Map集合中所有的value,返回一个Collection
Collection collection = map.values();
for (Object obj : collection){
System.out.print(obj); //zhangsan,wangwu,lisi,zhaoliu
}
}
}
08、void clear() 清空Map集合
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//清空Map集合
map.clear();
System.out.println(map.size()); //0
}
}
09、判断Map集合是否为空
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//清空Map集合
map.clear();
//判断是否为空
boolean b = map.isEmpty();
System.out.println(b); //true
}
}
10、遍历Map集合的方法
第一种方式: 获取所有的key,通过遍历key,来遍历value
import java.util.*;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//获取所有的key,所有的key是一个Set集合
Set<Integer> set = map.keySet();
//遍历Set集合,获取每一个key值,通过key值来获取value
//创建迭代器
Iterator<Integer> it = set.iterator();
while (it.hasNext()){
Integer Num = it.next();
String obj = map.get(Num);
System.out.println(Num + " " + obj);
}
}
}
第二种方法: Set<Map.Entry<K,V>> entrySet()
以上这个方法是把Map集合直接全部转换成Set集合。Set集合中元素的类型是 : Map.Entry
import java.util.*;
public class MapTest {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"wangwu");
map.put(3,"lisi");
map.put(4,"zhaoliu");
//把Map集合直接全部转换成Set集合
Set<Map.Entry<Integer,String>> set = map.entrySet();
//此时遍历Set集合,就相当于遍历了Map集合
for(Map.Entry<Integer,String> Node : set){
System.out.println(Node);
}
}
}
九、HashMap集合:
文末
js前端的重头戏,值得花大部分时间学习。
推荐通过书籍学习,《 JavaScript 高级程序设计(第 4 版)》你值得拥有。整本书内容质量都很高,尤其是前十章语言基础部分,建议多读几遍。
另外,大推一个网上教程 现代 JavaScript 教程 ,文章深入浅出,很容易理解,上面的内容几乎都是重点,而且充分发挥了网上教程的时效性和资料链接。
学习资料在精不在多,二者结合,定能构建你的 JavaScript 知识体系。
面试本质也是考试,面试题就起到很好的考纲作用。想要取得优秀的面试成绩,刷面试题是必须的,除非你样样精通。
这是288页的前端面试题
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ntrySet();
//此时遍历Set集合,就相当于遍历了Map集合
for(Map.Entry<Integer,String> Node : set){
System.out.println(Node);
}
}
}
## 九、HashMap集合:
### 文末
js前端的重头戏,值得花大部分时间学习。
![JavaScript知识](https://img-blog.csdnimg.cn/img_convert/701f4db8e7fc0c3ff4d87017d6c846be.png)
推荐通过书籍学习,《 JavaScript 高级程序设计(第 4 版)》你值得拥有。整本书内容质量都很高,尤其是前十章语言基础部分,建议多读几遍。
![前端电子书](https://img-blog.csdnimg.cn/img_convert/6065b7d33c9a5859971490467a967767.png)
另外,大推一个网上教程 现代 JavaScript 教程 ,文章深入浅出,很容易理解,上面的内容几乎都是重点,而且充分发挥了网上教程的时效性和资料链接。
学习资料在精不在多,二者结合,定能构建你的 JavaScript 知识体系。
面试本质也是考试,面试题就起到很好的考纲作用。想要取得优秀的面试成绩,刷面试题是必须的,除非你样样精通。
**这是288页的前端面试题**
![288页面试题](https://img-blog.csdnimg.cn/img_convert/6a0ed19303290ef201081fc6148f21db.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)**
[外链图片转存中...(img-vyTVyXMk-1713446588969)]
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**