Java集合框架整理

1.集合的概念

1.1 什么是集合

        概念:对象的容器,实现了对对象的常用操作。可实现数组的功能。

和数组区别:

        (1)数组长度固定,集合长度不固定;

        (2)数组可存储基本类型和引用类型,而集合只能存储引用类型;

2.Collection接口

2.1 collection体系结构

 2.2 Collection父接口

1.特点:代表一组任意类型的对象,无序、无下标、不能重复。

2.迭代方法(Iterator):

        (1)hasNext() : 有没有下一个元素;

        (2)next() : 获取下一个元素;

        (3)remove() : 删除当前元素;        

  public static void main(String[] args) {
        Collection collection =new ArrayList();
        collection.add("小王");
        collection.add("小刘");
        collection.add("小张");

        //(1)使用增强for循环遍历
        for(Object object : collection){
            System.out.println(object);
        }
        //(2)使用迭代器的方式(遍历集合的专属方法)
        Iterator it = collection.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }

注意:迭代过程当中不允许使用collection的其他方法改变集合的元素(并发修改异常)。

Iterator it = collection.iterator();
while(it.hasNext()){
    System.out.println(it.next());
    collection.remove(it.next());
}

但是如果仍要删除,可以使用 it.remove(),本质上删除的是上一个遍历过的元素;

(4)判断:collection.contains(); collection.isEmpty();

3.List接口与实现类

1. 特点:有序、有下标、元素可重复,必须开辟连续空间。

2. 遍历迭代:

       (1) 列表迭代器(List专属):ListIterator;

        (2)可以正序遍历,也可逆序遍历,相较于Iterator可遍历角标。

public static void main(String[] args) {
        List list =new ArrayList();
        list.add("小明");
        list.add("小红");
        list.add("小蓝");
        //使用for遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        //使用增强for
        for (Object object: list) {
            System.out.println(object);
        }
        //使用迭代器
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        //使用列表迭代器
        ListIterator lit = list.listIterator();
        //正序迭代
        while(lit.hasNext()){
            System.out.println(lit.nextIndex() + ":" + lit.next());
        }
        //逆序迭代
        while(lit.hasPrevious()){
            System.out.println(lit.previousIndex() + ":" + lit.previous());
        }
    }

3.集合中不能存储基本数据类型,因此存数字时会自动装箱,在删除某个数字的时候,调用remove方法直接删除该数字,需要将该数字进行装箱后删除。如 list.remove(new Integer(20)),当然利用角标也可以删除。

        list.subList(1,3),返回子集合,含头不含尾;

3.1 ArrayList[重点]

1. 存储结构:数组结构实现

2. 特点:查询块、增删慢,运行效率快、线程不安全;

3. 功能:和List一致;

4. 源码分析:

        (1)默认容量大小为 10;

注意:如果没有向集合中添加任何元素时,容量为 0,添加一个元素后,容量为10,超过之后会自动扩容。每次扩容都是原来的1.5倍,比如到达11的时候,此时容量为15。

        (2)elementData 用来存放元素的数组;

        (3)size为实际元素个数

3.2 Vector

1. 数组结构实现,查询快、增删慢;

2. jdk1.0版本,运行效率慢、线程安全;

 public static void main(String[] args) {
        Vector vector=new Vector();
        vector.add("苹果");
        vector.add("香蕉");
        vector.add("梨子");
        System.out.println("元素个数:" + vector.size());
        //2.遍历,使用枚举器
        Enumeration en = vector.elements();
        while (en.hasMoreElements()){
            String  o = (String) en.nextElement();
            System.out.println(o);
        }
        //3.判断
        System.out.println(vector.contains("苹果"));
        System.out.println(vector.isEmpty());
    }

3.3 LinkedList(链表结合)

      (1) 链表结构实现,增删快、查询慢;

      (2)存储结构:双向链表,无需开辟连续空间;

4. 泛型和工具类

1. Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。

2. 常见的形式有泛型类、泛型接口、泛型方法。

3. 语法:<T,....> , T称为类型占位符,表示一种引用类型,如果编写多个,用逗号隔开。

4. 好处:

        (1)提高代码的重用性

        (2)防止类型转换异常,提高代码的安全性。

注意:泛型只能使用引用类型,不同泛型类型之间不能相互赋值。

5. 泛型接口的两种使用方式:

第一种:在使用接口时就确定好泛型的类型;

public class MyInterfaceImpl implements MyInterface<String>{
    
}

第二种:使用时不确定泛型的类型,但是用的是泛型类实现接口。

public class MyInterfaceImpl<T> implements MyInterface<T>{
    
}

6. 泛型方法:

(1)语法:<T> 返回值类型

(2)使用:

//定义
public class MyGenericMethod {
    //泛型方法
    public <T> void show1(T t){
        System.out.println("泛型方法" + t);
    }

    public <T> T show2(T t){
        System.out.println("泛型方法" + t);
        return t;
    }
}
//使用
public class Test2 {
    public static void main(String[] args) {
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.show1("字符串");
        myGenericMethod.show1(200);

    }
}

7. 泛型方法在使用的时候无需指定参数的类型,传什么值就会自动匹配到值的类型。此方法类似于方法重载,在相同的参数条件下,一个泛型方法可代替多个重载方法,提高了代码的重用性。

8. 泛型集合:

(1)概念:参数化类型、类型安全的集合、强制集合元素的类型必须一致。

(2)特点:

  •         编译时即可检查,而非运行时抛出异常。
  •         访问时,不必类型转换(拆箱)。
  •         不同泛型之间引用不能相互赋值,泛型不存在多态。

5.Set接口与实现类

5.1 HashSet(重点)

1. 基于HashCode实现元素不重复;

2. 当存入元素的哈希码相同时,会调用equal进行确认,如果结果为true,则拒绝后者存入。

3. 存储结构:数组+链表+jdk1.8后有红黑树

4. 存储过程:

        (1)根据hashCode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。

        (2)再执行equals方法,如果equals方法为true,则认为重复,否则,形成链表。

5. 特点:

  • 基于HashCode计算元素存放位置
    • 利用31这个质数,减少散列冲突
      • 31提高执行效率 31 * i = (i << 5) - i 转为移位操作
    • 当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝后者存入
  •         新建集合 HashSet<String> hashSet = new HashSet<String>();
  •         添加元素 hashSet.add( );
  •         删除元素 hashSet.remove( );

6. 遍历操作

        (1)增强for for( type type : hashSet)

        ​(2)迭代器 Iterator<String> it = hashSet.iterator( );

7. 判断 hashSet.contains( ); hashSet.isEmpty();

5.2 TreeSet:

  •         基于排列顺序实现元素不重复。
  •         实现了sortedSet接口,对集合元素自动排序。
  •         元素对象的类型必须实现Comparable接口,指定排序规则。
  •         通过CompareTo方法确定是否为重复元素。

1. 存储结构:红黑树(左边节点比右边节点小)

        创建集合 TreeSet<String> treeSet = new TreeSet<>()

        添加元素 treeSet.add();

        删除元素 treeSet.remove();

        遍历 1. 增强for 2. 迭代器

        判断 treeSet.contains();

2. 补充:TreeSet集合的使用

        Comparator 实现定制比较(比较器)

        Comparable 可比较的(自己实现的比较规则)

// 重写compare
@override
public int compare(Person o1, Person o2){
  int n1 = o1.getAge()-o2.getAge();
  int n2 = o1.getName().comareTo(o2.getName());
  return n1 == 0 ? n2 : n1;
}

6.Map接口与实现类

1. 特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复。

2. 方法:

        V put(K key,V value) :将对象存入到集合中,关联键值。key重复则覆盖原值。

        Object get(Object key) :根据键获取对应的值;

        Set<K> :返回所有的 key;

        Collection<V> values():返回包含所有值的Collection集合。

        Set<Map.Entery<K,V>> :键值匹配的Set集合。

3. 遍历:有两种方法,一种是遍历keySet,一种是遍历map.entrySet(),map.entrySet()的遍历效率比keySet高,因为keySet只能遍历key,而获取值时需要调用map.get(key)方法,相当于再次遍历一次。

4. 方法案例:

   public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        //1.添加元素
        map.put("cn","中国");
        map.put("uk","英国");
        map.put("usa","美国");
        System.out.println(map.size());
        System.out.println(map.toString());
        //2.删除
        map.remove("usa");
        System.out.println(map.toString());
        //3.遍历
//        Set<String> keyset = map.keySet();
        for (String key: map.keySet()) {
            System.out.println(key + " : " + map.get(key));
        }
        System.out.println("--------------entry--------------");
        //3.2使用entrySet方法(键值对)
//        Set<Map.Entry<String,String>> entries = map.entrySet();
        for (Map.Entry<String,String> entry : map.entrySet()){
            System.out.println(entry.getKey()+ " : "+ entry.getValue());
        }
    }

5.1 HashMap(重点):

  •         存储结构:哈希表(数组+链表+红黑树);
  •         使用key可使hashcode和equals作为重复;
  •         JDK1.2版本,线程不安全,运行效率快;允许用null作为key或者value;
  •         增、删、遍历、判断与上述一致;

原码分析总结:

  1. HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
  2. 当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
  3. jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
  4. jdk1.8 当链表长度 <6 时 调整成链表
  5. jdk1.8 以前,链表时头插入,之后为尾插入

HashSet和HashMap之间的关系:

        在HashSet源码中,可以发现HashSet方法调用了HashMap,add方法中也用的是map.put()方法。总而言之,HashSet实质上调用了hashMap实现,拥有相同的结构。

Hashtable:

        线程安全,运行效率慢;不允许null作为key或是value;

Properties:

        hashtable的子类,要求key和value都是string,通常用于配置文件的读取;

TreeMap:

        存储结构:红黑树,因此存储对象需要实现Comparable接口;

        实现了SortedMap接口(是map的子接口),可以对key自动排序;

5.2 Collections

1. 概念:集合工具类,定义了除了存取以外的集合常用方法

2. 直接二分查找int i = Collections.binarySearch(list, x); 成功返回索引

3. 其他方法 : copy复制、reverse反转、shuffle打乱

// list转成数组
Integer[] arr = list.toArray(new Integer[10]);
sout(arr.length);
sout(Array.toString(arr));

// 数组转成集合
// 此时为受限集合,不能 添加和删除!
String[] name = {"张三","李四","王五"};
List<String> list2 = Arrays.asList(names);

// 把基本类型数组转为集合时,需要修改为包装类
Integer[] nums = {100, 200, 300, 400, 500};
List<Integer> list3 = Arrays.asList(nums);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记录菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值