2024年Web前端最全个人关于集合学习的笔记(超详细),2024年最新前端面试题web

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

}
}


总结:


重点:当集合的结构发生改变时,送代器必须重新获取,如果还是用以前老的送代器,会出现异常: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©;
       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 list = new ArrayList();
       Cat cat = new Cat();
       Bird bird = new Bird();
       list.add(cat);
       list.add(bird);
       //获取迭代器
       //表示这个迭代器中存储的是Animal类型的数据
       Iterator 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>和<T>


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<K> keySet() 获取Map集合所有的key(所有的键是一个set集合)


V remove(Object key) 通过key删除键值对


int size() 获Map集合中键值对的个数。


Collection<V> 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<V> 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 set = map.keySet();
       //遍历Set集合,获取每一个key值,通过key值来获取value
       //创建迭代器
       Iterator 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集合:


1、HashMap底层是哈希表/散列表的数据结构。


底层实际上是一个数组(一维数组)。


哈希表/散列表:一维数组,这个数组中每一个元素是一个单向链表。(数组和链表的结合体。)


2、哈希表是一个怎样的数据结构呢 ?


哈希表是一个数组和单向链表的结合体。


数组:在查询方面效率很高,随机增删方面效率很低。


单向链表:在随机增删方面效率较高,在查询方面效率很低。


哈希表将以上的两种数据结构融合在一起,充分发挥它们各自的优点。


3、HashMap集合的key部分特点:


无序,不可重复。


为什么无序?因为不一定挂到哪个单向链表上。


不可重复是怎么保证的??equals方法来保证HashMap集合的key不可重复


如果key重复了,value会覆盖。


放在HashMap集合key部分的元素其实就是放到HashSet集合中了。


所以HashSet集合中的元嘉也需要同时重写hashCode()和equals()方法


4、哈希表HashMap 使用不当时无法发挥性能!


假设将所有的hashCode()方法返回值固定为某个值,那么会导致底层哈希表变成了纯单向链表。这种情况我们称为:散列分布不均匀。


什么是散列分布均匀?


散列分布均与需要你重写hashCode()方法时有一定的技巧。


5、重点:放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时重写 hashCode和equals方法。


6、HashMap集合的默认初始化容量是16,默认加载因子是0.75。这个默认加载因子是当HashMap集合底层数组的容量达到75%的时候,数组开始扩容。


**重点:**记住: HashMap集合初始化容量必须是2的倍数,这也是官方推荐的,这是因为达到散列均匀,为了提高HashMap集合的存取效率,所必须的。


7、向Map集合中存,以及从Map集合中取,都是先调用key的hashCode方法,然后再调用equals方法!equals方法有可能调用,也有可能不调用。


拿put(k,v)举例,什么时候equals不会调用?


k.hashCode()方法返回哈希值,


哈希值经过哈希算法转换成数组下标。


数组下标位置上如果是null,equals不需要执行。


拿get(k)举例,什么时候equals不会调用?


k.hashCode()方法返回哈希值,


哈希值经过哈希算法转换成数组下标。


数组下标位置上如果是null,equals不需要执行。


8、 如果一个类的equals方法重写了,那么hashCode()方法必须重写。并且equals方法返回如果是true,hashCode()方法返回的值必须一样。equals方法返回true表示两个对象相同,在同一个单向链表上比较。那么对于同一个单向链表上的节点来说,他们的哈希值都是相同的。所以hashCode()方法的返回值也应该相同。


9、hashCode()方法和equals()方法,这两个方法需要同时生成。


10、**终极结论:**放在HashMap集合key部分的,以及放在HashSet集合中的元素,需要同时重与hashCode方法和equals方法。


11、对于哈希表数据结构来说 :


如果o1利o2的hash值相同,一定是放到同一个单向链表上。


当然如果o1和o2的hash值不同,但由于哈希算法执行结束之后转换的数组下标可能相同,此时会发生“哈希碰撞”




## 十、Hashtable集合


HashMap集合的key value 都是可以为null的。


Hashtable的key 可以为null吗?


Hashtable的key和value都是不能为null的。


HashMap集合的key和value 都是可以为null的。



Hashtable方法都带有synchronized : 线程安全的。线程安全有其它的方案,这个Hashtable对线程的处理导致效率较低,使用较少了。


Hashtable和HashMap 一样,底层都是哈希表数据结构。Hashtable的初始化容量是11,默认加载因子是:0.75f Hashtable的扩容是:原容量\* 2 + 1





## 十一、Properties


目前只需要掌properties属性类对象的相关方法即可。


Properties是一个Map集合,继Hashtable,Properties的key和value都是String类型。


Properties被称为属性类对象。


Properties是线程安全的。


**关于Properties的方法:**


setProperty() 存入字符串


getProperty() 取出字符串


示例代码:




import java.util.Properties;

public class PropertiesTest {
   public static void main(String[] args) {
       //创建Properties对象
       Properties properties = new Properties();
       //向Properties中存入数据
       properties.setProperty(“url”, “fiushdf”);
       properties.setProperty(“driver”, “mybitis”);
       properties.setProperty(“username”, “data”);
       properties.setProperty(“password”, “123456”);
       //在Properties中取出数据(通过key来获取value)
      String url =  properties.getProperty(“url”);
      String driver =  properties.getProperty(“driver”);
      String username =  properties.getProperty(“username”);
      String password =  properties.getProperty(“password”);
       System.out.println(url);
       System.out.println(driver);
       System.out.println(username);
       System.out.println(password);
  }
}




## 十二、TreeSet集合


1、TreeSet集合底层实际上是一个TreeMap。


2、TreeMap集合底层是一个二叉树。


3、放到TreeSet集合中的元素,等同于放到TreeMap集合key部分了。


4、TreeSet集合中的元素:无序不可重复,但是可以按照元素的大小顺序自动排序称为:可排序集合。


代码示例:(自定义类如何进行排序)


第一种方式:



package homework;


import java.util.TreeSet;

public class TreeSetTest {
   public static void main(String[] args) {
       //创建一个TreeSet对象
       TreeSet vips = new TreeSet<>();
       //向vips中添加对象
       vips.add(new Vip(“zhangsan”,12));
       vips.add(new Vip(“lisi”,79));
       vips.add(new Vip(“wangwu”,79));
       vips.add(new Vip(“bgwu”,56));
       //遍历vips集合
       for (Vip vip : vips){
           System.out.println(vip);
      }
  }
}
class Vip implements Comparable{

最后

你要问前端开发难不难,我就得说计算机领域里常说的一句话,这句话就是『难的不会,会的不难』,对于不熟悉某领域技术的人来说,因为不了解所以产生神秘感,神秘感就会让人感觉很难,也就是『难的不会』;当学会这项技术之后,知道什么什么技术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

我特地针对初学者整理一套前端学习资料

前端路线图

vue.js的36个技巧

素:无序不可重复,但是可以按照元素的大小顺序自动排序称为:可排序集合。

代码示例:(自定义类如何进行排序)

第一种方式:

package homework;
​
​
import java.util.TreeSet;
​
public class TreeSetTest {
    public static void main(String[] args) {
        //创建一个TreeSet对象
        TreeSet<Vip> vips = new TreeSet<>();
        //向vips中添加对象
        vips.add(new Vip("zhangsan",12));
        vips.add(new Vip("lisi",79));
        vips.add(new Vip("wangwu",79));
        vips.add(new Vip("bgwu",56));
        //遍历vips集合
        for (Vip vip : vips){
            System.out.println(vip);
        }
    }
}
class Vip implements Comparable<Vip>{


### 最后

你要问前端开发难不难,我就得说计算机领域里常说的一句话,这句话就是『**难的不会,会的不难**』,对于不熟悉某领域技术的人来说,因为不了解所以产生神秘感,神秘感就会让人感觉很难,也就是『难的不会』;当学会这项技术之后,知道什么什么技术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

**我特地针对初学者整理一套前端学习资料**

[外链图片转存中...(img-ldu4fXli-1715394357314)]

[外链图片转存中...(img-LbEYGf6s-1715394357315)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值