Java基础之集合框架的学习 2023-4-28

本文笔记来源于本人自学尚硅谷java最新基础课程而来

1. 集合框架的概述

1.1 数据存储的容器

内存层面需要针对于多个数据进行存储。
此时,可以考虑的容器有:集合Collection 和 数组

1.2 数组的特点和弊端
  • 特点: #java了解
    • 数组一旦初始化,其长度就是确定的。
    • 数组中的多个元素是依次紧密排列的,有序的,可重复的
    • (优点)数组一旦初始化完成,其元素的类型就是确定的,不是此类型的元素,就不能添加到此数组中。
      int[] arr = new int[10];  
      arr[0] = 1;  
      arr[1] = "AA"; //编译会报错  
    
      Object[] arr1 = new Object[10];  
      arr1[0] = new String();  
      arr1[1] = new Date();  
    
    (优点)元素的类型既可以是基本数据类型,也可以是引用数据类型  
  
- 弊端:    
    - 数组一旦初始化,其长度就不可变了  
    - 数组中存储数据特点的单一性。对于无序的、不可重复的场景的多个数据就无能为力了  
    - 数组中可用的方法、属性极少。具体的需求,都需要自己来组织相关的代码逻辑。  
    - 针对于数组中元素的输出、插入操作,性能较差  
  
#### 1.3  Java集合框架体系(java.util包下)(重点)  
```java
java.util.Collection 存储一个个的数据  
    子接口:List ---> 有序的、可重复的数据  类似于 “动态”数组  
        实现类: ArrayList(主要实现类)、LinkedList、Vector  
  
    子接口:Set ---> 无序的、不可重复的数据  类似于数学上的集合  
        实现类: HashSet(主要实现类)、 LinkedHashSet、TreeSet  
  
java.util.Map 存储一对一对的数据(key-value键值对,(x1,y1)、(x2,y2) 类似于数学上的 y = f(x) ,  
    实现类:HashMap(主要实现类)、LinkedHashMap、TreeMap、Hashtable、Properties
1.4 学习的程度把握:(逐步递进的)
  • 掌握Collection接口的主要方法(15个),主要实现类的方法,会实例化,会选取合适的实现类

  • 明确不同实现类的区别

  • 针对常用的实现类知道底层的原码,熟悉常见的数据结构(第14章讲解)

2. Collection的常用方法

2.1 常用方法:(Collection中定义了15个抽象方法。这些方法需要熟悉!)
add (Object obj)  
addAll(Collection coll)  
clear()  
isEmpty()  
size()  
contains(Object obj)  
containsAll(Collection coll)  
retainAll(Collection coll)  //只保留交集,及两个集合中相同的部分!!!  
remove(Object obj)  
removeAll(Collection coll)  //删除交集  
hashCode()  
equals()  
toArray()  
---  
iterator()  
2.2 集合与数组的相互转换:
  • 针对于方法的一些参数

集合—>数组: toArray()

数组—>集合: Arrays.asList(Object … obj) //注意是对象传入!!! 返回的是一个List集合类

//数组--->集合  
        Object[] o1 = new Object[]{"aa",1312,"new",new Person("jerry",12)};  
        Collection coll1 = Arrays.asList(o1);  
        System.out.println(coll1);  
  
        Integer[] i1 = new Integer[]{1,2,3};  
        Collection coll2 = Arrays.asList(i1);  
        System.out.println(coll2);  
        System.out.println(coll2.size());  //3
  
        int[] i2 = new int[]{1,2,3};  
        Collection coll3 = Arrays.asList(i2);  
        System.out.println(coll3);  
        System.out.println(coll3.size()); //1
2.3 向Collection中添加元素的要求:
要求元素所属的类必须要重写equals()方法!!!  

原因:
Collection中的一些方法(如:contains() / remove() )在使用时,要调用元素所在类的equals()方法
若没有重写,则比较的地址值,无法删除集合中字面上相同的元素
如:

    Person p1 = new Person("lihua",25);  
    Person p2 = new Person("lihua",25);  
  
    Collection coll = new ArrayList();  
  
    coll.add(p1);  
  
    coll.remove(p2); //无法删除,无法找到该对象,因为此时比较的是地址值

3. 迭代器和增强for循环

3.1 迭代器(Iterator)的作用?
  • 用来遍历集合元素的
  • 补充:
    • 迭代器是一个接口(java.util.Iterator)
    • 是设计模式的一种
    • 不负责数据的存储,赋值集合类的遍历
3.2 如何获取迭代器(Iterator)对象?
Iterator iterator = coll.iterator();  
3.3 如何实现遍历(代码实现)
while(iterator.hasNext()){  
    System.out.println(iterator.next());            
    //①指针下移;②将下移后集合位置上的元素返回  
} 
3. 4 增强for循环(foreach循环)的使用(jdk5.0新特性)
  • 作用

    遍历数组和集合

  • 格式

for(数组或集合中的元素类型 临时变量: 数组或集合){  
    操作临时变量的输出  
}  
  • 说明:
    • 针对于集合来说,增强for循环的底层仍然使用的是迭代器
    • 增强for循环的执行过程中,是讲集合或数组中的元素依次赋值给临时变量
      • 注意!!!
      • 循环体中对临时变量的修改,可能不会导致原有集合或数组中元素的修改

4. List

4.1 List接口中存储数据的特点

用于储存有序的、可以重复的数据 —> 使用List代替数组,“动态”数组 (ArrayList)

4.2 List中的常用方法

第1波:Collection中的15个方法

第2波:

  • 小结(必须记住!!!) #java记忆点
    • 增: add(Object obj) / addAll(Collection coll)
    • 删: remove(Object obj) / remove(int index) 注意数据类型!!!
    • 改: set(int index, Object ele)
    • 查: get(int index)
    • 插: add(int index ,Object ele) / addAll(int index, Collection eles)
    • 长度: size()
    • 遍历: iterator() / 增强for循环 / for循环
4. 3 List及其实现类特点
- java.util.Collection:储存一个个的数据  
    - 子接口,List:储存 有序的,可重复的数据(“动态”数组)  
        - ArrayList:  
            List的主要实现类;线程不安全,效率高;底层使用Object[]数组进行存储  
            在添加数据、查找数据时,效率较高(直接索引可以找到,复杂度为o(1));  
            在插入、删除数据时,效率较低(一个个前移/后移,复杂度为o(n));  
        - LinkedList:  
            底层使用双向链表的方式进行存储;            在对集合中的数据进行频繁的删除、插入操作时,效率较高(对链进行操作,复杂度为o(1));  
            在添加数据、查找数据时,效率较低(根据链一个个的查,复杂度为o(n))  
        - Vector:  
            List的古老实现类;线程安全的,效率低;底层使用Object[]数组进行存储

5. Set(熟悉)

熟悉熟悉就可以了

5.1 Set及其实现类特点
- java.util.Collection  
    - 子接口:set ---> 存储无序的、不可重复的数据(高中学习的集合)  
        - 实现类:HashSet(主要实现类) ---> 底层使用的是HashMap,即使用数组、单向链表和红黑树结构进行存储  
            - 其子类:LinkedHashSet ---> 是HashSet的子类,在现有结构的基础上又加上了一组双向链表。  
            即:我们可以按照添加元素的顺序实现遍历。便于频繁的查询操作  
        - TreeSet:底层使用红黑树存储。可以按照添加的元素的指定的属性的大小顺序进行遍历  
5.2 开发中的使用频率及场景
  • 较List Map来说,Set的使用频率较低
  • 原来过滤重复的数据
5.3 Set中常用方法
  • 即为Collection中声明的15个抽象方法。没有新增的方法
5.4 Set中无序性、不可重复性的理解 #java注意点
  • 无序性:

    • != 随机性
    • 添加元素的顺序和遍历元素的顺序不一致,是不是就是无序性呢?不是的
    • 到底声明是无序性? 与添加的元素的位置有关,不想ArrayList那样是依次紧密排列的
    • 这里是根据添加元素的哈希值,计算的其在数组中的存储位置。此位置不是依次排列的,表现为无序性!!!
  • 不可重复性

    • 添加到Set中的元素是不可相同的。
    • 比较的标准,先判断hashCode()的到的哈希值,若相同就在判断equals()得到的boolean类型的结果
    • 哈希值相同&&equals返回true,则元素是相同的。
5.5 添加到HashSet/LinkedHashSet中元素的要求:(由5.3引出)
  • 要求元素的equals() 和 hashCode() 方法必须重写
  • 要求两个方法保持一致性,我们只需要在IDEA中自动生成这两个方法即可
5.6 TreeSet的使用(了解即可,主要熟悉两个比较器)

6.1 底层的数据结构:

  • 红黑树结构

6.2 添加数据后的特点:

  • 可以按照添加的元素中,指定的属性的大小顺序,进行遍历

6.3 向TreeSet中添加的元素的要求:

  • 添加到TreeSet中的元素必须是一个类型的对象,否则会报ClassCastException
  • 添加的元素需要考虑排序:自然排序 / 定制排序

6.4 判断数据是否相同的标准

  • 不用在考虑hashCode()和equals()方法了,也就意味着添加到TreeSet中的元素所在的类不用重写这两个方法
  • 比较元素的带下的标准就是考虑自然排序/定制排序中的compareTo(Object obj)/compaer(Object obj1,Object obj2)的返回值
  • 如果返回值为0,则相同,所以后一个相等的元素就不能添加到TreeSet中了

6. Map

6.1 Map及其实现类对比

储存一堆一堆的数据(entry:key-value 键值对,类似于高中的函数)

- HashMap(主要实现类):线程不安全,效率高;可以添加null的key和value值;底层使用数组,单向链表和红黑树结构存储(jdk8)  
    - LinkedHashMap :是HashMap的子类,在HashMap使用的数据结构的基础上,增加了一对双向链表,用于记录添加的元素的先后顺序,进而我们在遍历元素的时候,就可以按照添加的顺序显示  
    开发中,对于频繁的遍历操作,建议使用此类- TreeMap :底层使用红黑树储存;可以按照添加的key-value中的key元素的制定的属性的大小顺序进行遍历,需要考虑使用自然排序和定制排序  
- Maptable :古老实现类;线程安全的,效率低;不可以添加null的key和value;底层使用数组和单向链表储存  
    - Properties :其key和value都是String类型的。常用来处理属性文件

[面试题] #java重点

  • 区分HashMap和Hashtable
  • 区分HashMap和LinkedHashMap
  • HashMap的底层实现(①new HashMap;②put(key,value))
6.2 HashMap中元素的特点(熟悉!!!)
  • 所有的key彼此之间是不可重复的、无序的。所以key就构成了一个Set集合。—> key所在的类要求重写hashCode()和equals()方法

  • 所有的value彼此之间是可重复、无序的。所以value就构成了一个Collection集合。 —> value所在的类要重写equals()方法

  • 一个key-value就构成了一个entry(node)

  • 所有的entry彼此之间是不可重复的、无序的。所以entry就构成了一个Set集合。

6.3 Map中的常用方法

小结:(记住!!!)

  • 增: put(Object key,Object value) / putAll(Map m)
  • 删: Object remove(Object key)
  • 改: put(Object key,Object value) / putAll(Map m)
  • 查: Object get(Object key)
  • 插: 无序的,无法插入
  • 长度: size()
  • 遍历:
    • 遍历key集: Set keySet()
    • 遍历value集: Collection values()
    • 遍历entry集: Set entrySet()
6.4 TreeMap的使用(了解)
  • 底层使用红黑树结构
  • 可以按照添加的key-value中的key元素的指定的属性的大小顺序进行遍历
  • 需要考虑使用自然排序或导致排序
  • 要求!!! 添加到key中的元素必须是一个类型的对象
6.5 Hashtable与Properties的使用(重点的,在io中比较重要)
  • Properties是Hashtable的子类,其key和value都是String类型的,常用来处理属性文件。

  • Properties的使用实例

    public class PropertiesTest {
        @Test
        public void test() throws IOException { //注意:因为设计到流的操作,为了确保流能关闭,建议使用try-catch-finally
            //方式1:数据和代码耦合度高;如果修改的话,需要重写的编译代码、打包发布,繁琐
            //数据
    //        String name = "Tom";
    //        String password = "abc123";
    
            //代码:用于操作name,password
            //...
    
            //方式2:将数据封装到具体的配置文件中,在程序中读取配置文件中的信息。实现了
            //数据和代码的解耦;由于我们没有修改代码,就省去了重新编译和打包的过程。
            File file = new File("info.properties"); //注意,要提前创建好
    //        System.out.println(file.getAbsolutePath());
            FileInputStream fis = new FileInputStream(file);
    
            Properties pros = new Properties();
            pros.load(fis); //加载流中的文件中的数据
    
            //读取数据
            String name = pros.getProperty("name");
            String pwd = pros.getProperty("password");
    
            System.out.println(name + ":" + pwd);
    
            fis.close();
        }
    
    }
    

7. Collections工具类的使用

7.1 Collections概述
  • Collection是一个操作Set、List、Map等集合的工具类
7.2 常用方法

排序操作:

- reverse(List):反转 List 中元素的顺序  
- shuffle(List):对 List 集合元素进行随机排序  
- sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序  
- sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序  
- swap(List,intint):将指定 list 集合中的 i 处元素和 j 处元素进行交换  

查找

- Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素  
- Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素  
- Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素  
- Object min(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最小元素  
- int binarySearch(List list,T key)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须是有序的,否则结果不确定。  
- int binarySearch(List list,T key,Comparator c)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序过的,否则结果不确定。  
- int frequency(Collection c,Object o):返回指定集合中指定元素的出现次数  

复制、替换

- void copy(List dest,List src):将src中的内容复制到dest中  
- boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值  
- 提供了多个unmodifiableXxx()方法,该方法返回指定 Xxx的不可修改的视图。  

添加

- boolean addAll(Collection  c,T... elements)将所有指定元素添加到指定 collection 中。  

同步

- Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题  

实例:扑克牌例子

public class Exer {  
  public static void main(String[] args) {  
      String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};  
      String[] color = {"方片♦","梅花♣","红桃♥","黑桃♠"};  
      ArrayList poker = new ArrayList();  
      //组牌(每个花色对应不同的数字,最后加上大王和小王)  
      for (int i = 0; i < color.length; i++) {  
          for (int j = 0; j < num.length; j++) {  
              //把每个牌都放进去  
              poker.add(color[i] + num[j]);  
          }  
      }  
      poker.add("大王");  
      poker.add("小王");  
      //洗牌  
      Collections.shuffle(poker);  
      //发牌  
      List Tom = new ArrayList();  
      List Jerry = new ArrayList();  
      List me = new ArrayList();  
      List last = new ArrayList();  

      for (int i = 0; i < poker.size(); i++) {  
          if(i> poker.size()-4){  
              last.add(poker.get(i));  
          }  
          if (i%3==0){  
              Tom.add(poker.get(i));  
          }else if (i%2==0){  
              Jerry.add(poker.get(i));  
          }else if (i%1==0){  
              me.add(poker.get(i));  
          }  
      }  

      System.out.println("Tom:");  

      System.out.println(Tom);  
      System.out.println("Jerry:");  
      System.out.println(Jerry);  
      System.out.println("me:");  
      System.out.println(me);  
      System.out.println("last:");  
      System.out.println(last);  

      //进一步思考如何将得到的牌排好序,
      //提示:
      //HashMap,其中key为下标,value为poker
  }  
}
7.3 面试题:区分Collection 和 Collections(需要知道,其他了解)

Collection:集合框架中的用于存储一个一个元素的接口,又分为List和Set等子接口。
Collections:用于操作集合框架的一个工具类。此时的集合框架包括:Set、List、Map

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值