Java集合

1.集合结构图

在这里插入图片描述
在这里插入图片描述

2.数组和集合

在这里插入图片描述
在这里插入图片描述

3.Collection接口

3.1 Collection接口和常用方法

在这里插入图片描述
测试常用方法:对于remove,可删除对象也可按照下标删除,下标优先。

package com.collection_;

import java.util.ArrayList;
import java.util.List;

/**
 * Created on 2021/6/22.
 *
 * @author Ryan_小王
 */
@SuppressWarnings({"all"})
public class Test {
    public static void main(String[] args) {
        List arrayList = new ArrayList();
        arrayList.add("wcw");
        arrayList.add("wj");
        arrayList.add(10);
        arrayList.add(0,12);
        arrayList.remove(0);
        System.out.println(arrayList);
        System.out.println(arrayList.contains("wcw"));
        System.out.println(arrayList.size());
        System.out.println(arrayList.isEmpty());
        arrayList.clear();
        //添加多个元素
        List arrayList1 = new ArrayList();
        arrayList1.add(13);
        arrayList1.add("wc");
        arrayList.addAll(arrayList1);
        System.out.println(arrayList.containsAll(arrayList1));
        arrayList.removeAll(arrayList1);
        System.out.println(arrayList);

    }
}

3.2 Collection接口遍历元素

方式1:使用Iterator(迭代器)

  • Iterator对象称为迭代器,主要用于遍历Collection集合中的元素
  • 实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器。
  • Iterator仅用于遍历集合,Iterator本身并不存放对象。
package com.collection_;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * Created on 2021/6/22.
 *
 * @author Ryan_小王
 */
public class CollectionIterator {
    public static void main(String[] args) {
        Collection coll = new ArrayList();

        coll.add("wcw");
        coll.add(12);
        coll.add("hsp");
        
        Iterator iterator = coll.iterator();
        //hashNext():判断是否还有下一个元素
        //快捷键itit
        while (iterator.hasNext()) {
            //next():1.下移动 2.将下移以后集合位置上的元素返回
            Object obj = iterator.next();
            System.out.println(obj);
        }
    }
}

方式2:使用增强for,在Collection集合

1.使用增强for,在Collection集合
2.增强for,底层仍然是迭代器
3.增强for可以理解成就是简化版本的迭代器遍历
4.增强for可以直接用于数组
package com.collection_;

import java.util.ArrayList;
import java.util.Collection;

/**
 * Created on 2021/6/22.
 *
 * @author Ryan_小王
 */
public class CollectionIterator {
    public static void main(String[] args) {
        Collection coll = new ArrayList();

        coll.add("wcw");
        coll.add(12);
        coll.add("hsp");

        //1.使用增强for,在Collection集合
        //2.增强for,底层仍然是迭代器
        //3.增强for可以理解成就是简化版本的迭代器遍历
        for (Object obj: coll) {
            System.out.println("元素:" + obj);
        }
        
        //增强for可以直接用于数组
        int[] nums = {1, 2, 4};
        for (int i: nums) {
            System.out.println(i);
        }
        
    }
}

3.3 List

1.基本介绍

List接口是Collection接口的子接口,List集合类中元素有序且可重复,支持索引访问,实现List接口常用的类有:ArrayList、LinkedList和Vector。

2.List接口常用方法在这里插入图片描述
3.List三种遍历

多一个普通for循环获取:
1.使用增强for
2.使用Iterator(迭代器)
3.普通for循环,因为ArrayList底层其实是数组。

package com.collection_;

import java.util.ArrayList;
import java.util.List;

/**
 * Created on 2021/6/22.
 *
 * @author Ryan_小王
 */
public class CollectionIterator {
    public static void main(String[] args) {
        List list = new ArrayList();

        list.add("wcw");
        list.add(12);
        list.add("hsp");


        //1.使用增强for,在Collection集合
        //2.增强for,底层仍然是迭代器
        //3.增强for可以理解成就是简化版本的迭代器遍历
        for (Object obj: list) {
            System.out.println("元素:" + obj);
        }
        
		Iterator iterator = coll.iterator();
        //hashNext():判断是否还有下一个元素
        //快捷键itit
        while (iterator.hasNext()) {
            //next():1.下移动 2.将下移以后集合位置上的元素返回
            Object obj = iterator.next();
            System.out.println(obj);
        }
    }

        //使用普通for循环
        for (int i=0; i < list.size(); i++) {
            Object obj = list.get(i);
            System.out.println(obj);
        }

    }
}

3.3.1 ArrayList扩容机制

1.ArrayList中维护了一个Object类型的数组elementData。

2.当创建ArrayList对象时,若使用无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需再次扩容,则扩容elementData为1.5倍。

3.若使用自定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
在这里插入图片描述
无参构造器扩容流程图:
在这里插入图片描述
自定大小的构造器扩容机制
在这里插入图片描述
第一次扩容就按照elementData的1.5倍扩容,整个流程和前面的一样。

3.3.2 Vector

1.基本介绍

Vector底层也是一个对象数组,Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized。在开发中,需要线程同步安全时,考虑使用Vector,若是单线程则可以使用ArrayList,效率更高一点。
在这里插入图片描述
2.ArrayList和Vector的比较

扩容机制不同,ArrayList不是线程安全,Vector是线程安全。
在这里插入图片描述

3.3.3 LinkedList

1.基本介绍
在这里插入图片描述
在这里插入图片描述
双向链表的定义和使用举例:

package com.collection_;

/**
 * Created on 2021/6/23.
 *
 * @author Ryan_小王
 */
public class LinkedList01 {
    public static void main(String[] args) {
        Node jack = new Node("Jack");
        Node mike = new Node("Mike");
        Node smith = new Node("Smith");

        //链接起来
        jack.next = mike;
        mike.next = smith;
        smith.pre = mike;
        mike.pre = jack;

        //头指针和尾指针
        Node first = jack;
        Node last = smith;

        System.out.println("======正向遍历======");
        //正向遍历
        while (true) {
            if (first == null) {
                break;
            }
            System.out.println(first);
            first = first.next;
        }


        System.out.println("=======反向遍历=======");
        //反向遍历
        while (true) {
            if (last == null) {
                break;
            }
            System.out.println(last);
            last = last.pre;
        }
    }
}

class Node {
    public Object item;
    public Node next;
    public Node pre;

    public Node(Object name) {
        this.item = name;
    }

    public String toString() {
        return "name=" +item;
    }
}


2.ArrayList和LinkedList的比较

底层实现不同,ArrayList底层是可变数组,LinkedList底层实现是双向链表;增删效率不同,ArrayList增删效率较低,因为涉及到数组扩容,LinkedList增删效率较高,通过链表追加;改查效率不同,ArrayList较高,可直接索引找到,LinkedList较低,得从头开始。
在这里插入图片描述

3.4 Set

1.基本介绍

  1. 无序
  2. 不允许重复,只允许一个null
  3. Set接口实现类:HashSet、TreeSet、LinkedHashSet…

在这里插入图片描述

3.4.1 HashSet

1.基本介绍

  1. HashSet实现了Set接口,HashSet底层是HashMap,HashMap底层是(数组+链表+红黑树
  2. 可以存放null值,但是只能有一个null
  3. HashSet不保证元素是有序的,取决于hash后,再确定索引的结果.(即,不能保证存放元素的顺序和取出顺序一致).
  4. 不能有重复元素/对象
    在这里插入图片描述

2.底层机制说明

  1. HashSet添加元素底层实现(hashCode()+equals()).
  2. HashSet的扩容转成红黑树机制

注意:加入第一个元素时候扩容到16,临界值为12,加入前八个到同一链表,此时数组还是16,加入第九个元素时候,数组扩容机制启动,数组扩容到32,临界值为24。
在这里插入图片描述

练习:在HashSet集合中添加员工,若name和age相同则不能添加,归根到底就是重写equals()和hashcode()方法。

package com.collection_;

import java.util.HashSet;
import java.util.Objects;

/**
 * Created on 2021/6/25.
 *
 * @author Ryan_小王
 */
public class HashSetEx01 {
    public static void main(String[] args) {
        Employee wcw = new Employee("wcw", 12);
        Employee wc = new Employee("wc", 12);
        Employee wcw2 = new Employee("wcw", 12);

        HashSet hashSet = new HashSet();
        hashSet.add(wcw);
        hashSet.add(wc);
        hashSet.add(wcw2);

        System.out.println(hashSet);



    }
}

class Employee {
    private String name;
    private  int age;

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return age == employee.age &&
                Objects.equals(name, employee.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}


3.4.2 LinkedHashSet

1.基本说明
只是换成了双向链表,这样可以保证元素插入和取出顺序一致。其余的操作和扩容机制和HashSet一样。

注意:HashSet和LinkedHashSet一个是存放Node类型,一个是存放Entry类型。

HashSet的table维护的是Node类对象数组,Node是HashMap的静态内部类,插入的元素也是Node类的对象。
在这里插入图片描述LinkedHashSet维护也是Node类对象数组,Node是HashMap的内部类,插入的元素是Entry类的对象。Entry是Node的子类。在这里插入图片描述
2.全面说明
在这里插入图片描述
在这里插入图片描述

3.4.3 TreeSet

底层是TreeMap,可以排序,通过传入实现了Comparator接口的匿名内部类,重写compare()方法定制排序规则。

package com.collection_;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * Created on 2021/6/27.
 *
 * @author Ryan_小王
 */
@SuppressWarnings({"all"})
public class TreeSet_ {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o2).compareTo((String)o1);
            }
        });
        treeSet.add("tom");
        treeSet.add("jack");
        treeSet.add("so");
        treeSet.add("bom");
        treeSet.add("a");
        System.out.println(treeSet);
    }
}

//结果:[tom, so, jack, bom, a]

注意:重写了compare()方法,会根据该方法判断元素是否加入,如下举例中,根据字符串的长度来排序,"bom"和"tom"的长度都是3,则不会被加入,最终的结果为[a, so, tom, jack]

package com.collection_;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * Created on 2021/6/27.
 *
 * @author Ryan_小王
 */
@SuppressWarnings({"all"})
public class TreeSet_ {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length() - ((String)o2).length();
            }
        });
        treeSet.add("tom");
        treeSet.add("jack");
        treeSet.add("so");
        treeSet.add("bom");
        treeSet.add("a");
        System.out.println(treeSet);
    }
}

//结果:[a, so, tom, jack]

4.Map接口

1.基本介绍
在这里插入图片描述

4.1 HashMap

1.Map接口的特点

EntrySet存放的Entry只是指向,真正存放数据的地方还是在HashMap的Node。
在这里插入图片描述

1.k-v最后是HashMap$Node node = newNode(hash, key, value, null)

2.k-v为了方便程序员遍历,还会创建EntrySet集合,该集合存放的元素类型是Entry,而一个Entry对象就有k,v EntrySet<Entry<K,V>> 即:transient Set<Map.Entry<K,V>> entrySet;
3.entrySet中,定义的类型是Map.Entry,但是实际上存放的还是HashMap$Node ,这是因为 static class Node<K, V> implements Map.Entry<K, V>
4.当把HashMap$Node对象存放到entrySet就方便我们的遍历,因为Map.Entry提供了重要的方法 ,K getKey(); V getValue()

//1.k-v最后是HashMap$Node node = newNode(hash, key, value, null)
//2.k-v为了方便程序员遍历,还会创建EntrySet集合,改集合存放的元素类型是Entry,而一个Entry
// 对象就有k,v EntrySet<Entry<K,V>> 即:transient Set<Map.Entry<K,V>> entrySet;
//3.entrySet中,定义的类型是Map.Entry,但是实际上存放的还是HashMap$Node
// 这是因为 static class Node<K, V> implements Map.Entry<K, V>
//4.当把HashMap$nODE对象存放到entrySet就方便我们的遍历,因为Map.Entry提供了重要的方法
// K getKey(); V getValue()
HashMap hashMap = new HashMap();
hashMap.put("no1", "wcw");
hashMap.put("no2", "wc");


Set set = hashMap.entrySet();
System.out.println(set.getClass()); //HashMap$EntrySet
for (Object obj: set) {
    System.out.println(obj.getClass()); // HashMap$Node
    Map.Entry entry = (Map.Entry) obj;
    System.out.println("key=" + entry.getKey() + " value=" + entry.getValue());
}

2.Map接口常用方法
在这里插入图片描述
在这里插入图片描述
3.Map接口遍历
在这里插入图片描述
第一组:先取出所有的Key,通过Key取出所有的Value,取出的keyset是一个Set类型的集合,通过增强for或者迭代器遍历取出后,通过HashMap的get()方法获取value。

Set keyset = hashMap.keySet();

第二组:把所有的values取出,取出的为一个Collection类型的集合,同样通过增强for或者迭代器遍历取出value。

Collection coll = hashMap.values();

第三组:通过entrySet取出

Set entrySet = hashMap.entrySet();
for (Object obj: entrySet) {
    Map.Entry entry = (Map.Entry) obj;
    System.out.println(entry.getKey() + "-" + entry.getValue());
}

完整代码示例:

package com.collection_;

import java.util.*;

/**
 * Created on 2021/6/26.
 *
 * @author Ryan_小王
 */
public class HashMap_ {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();

        hashMap.put(1, "wcw");
        hashMap.put(2, "wc");
        hashMap.put(3, "wj");
        System.out.println(hashMap);

        //第一组:先取出所有的Key,通过Key取出所有的Value
        Set keyset = hashMap.keySet();
        //(1)增强for
        System.out.println("===第一种方式===");
        for (Object key: keyset) {
            System.out.println(key + "-" + hashMap.get(key));
        }

        //(2)迭代器
        System.out.println("===第二种方式===");
        Iterator iterator = keyset.iterator();
        while (iterator.hasNext()) {
            Object object = iterator.next();
            System.out.println(object + "-" + hashMap.get(object));
        }

        //第二组:把所有的values取出
        Collection coll = hashMap.values();
        //(1)增强for
        System.out.println("取出所有的value(增强for)");
        for (Object value: coll) {
            System.out.println(value);
        }
        //(2)迭代器
        System.out.println("取出所有vaule(迭代器)");
        Iterator iterator1 = coll.iterator();
        while (iterator1.hasNext()) {
            Object value = iterator1.next();
            System.out.println(value);
        }

        //第三组:entrySet
        System.out.println("通过entrySet");
        Set entrySet = hashMap.entrySet();
        for (Object obj: entrySet) {
//            System.out.println(obj);
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey() + "-" + entry.getValue());
        }
    }
}

4.HashMap小结
在这里插入图片描述
5.HashMap底层机制

实际存储的为HashMap$Node,它实现了Map$Entry接口。
在这里插入图片描述

在这里插入图片描述

4.2 Hashtable

1.基本介绍
在这里插入图片描述

2.扩容机制

第一次加数据数组扩容为11,达到临界值8,再次加入数据时数组容量就乘以2然后加1变为23,临界值为23*0.75=17。
在这里插入图片描述
3.Hashtable和HashMap对比
在这里插入图片描述

4.3 Properties

在这里插入图片描述
在这里插入图片描述

4.4 TreeMap

可以排序,通过传入实现了Comparator接口的匿名内部类,重写compare()方法定制排序规则。

注意:重写了compare()方法,会根据该方法判断元素是否加入,如下举例中,根据字符串的长度来排序,"bom"和"tom"的长度都是3,则不会被加入,最终的结果为{a=5, so=3, tom=4, jack=2}

package com.collection_;

import java.util.Comparator;
import java.util.TreeMap;

/**
 * Created on 2021/6/27.
 *
 * @author Ryan_小王
 */
@SuppressWarnings({"all"})
public class TreeMap_ {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length() - ((String)o2).length();
            }
        });
        treeMap.put("tom",1);
        treeMap.put("jack",2);
        treeMap.put("so",3);
        treeMap.put("bom",4);
        treeMap.put("a",5);
        System.out.println(treeMap);
    }
}

//结果:{a=5, so=3, tom=4, jack=2}

5.开发中如何选择集合实现类

在这里插入图片描述

6.Collections工具类


我喜欢

:拷贝时候,dest的size()大小应该和原先数组一样。

package com.collection_;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * Created on 2021/6/22.
 *
 * @author Ryan_小王
 */
@SuppressWarnings({"all"})
public class ArrayList01 {
    public static void main(String[] args) {
        // 无参构造器
        ArrayList arrayList= new ArrayList(8);
        for (int i = 1; i <= 10; i++) {
            arrayList.add(i);
        }

        for (int i = 1; i <=15; i++) {
            arrayList.add(i);
        }

        arrayList.add(10);

        System.out.println(arrayList);
        //排序
        Collections.sort(arrayList, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return (Integer)o2 - (Integer) o1;
            }
        });
        //反转
        Collections.reverse(arrayList);
        System.out.println(arrayList);
        //打乱
        Collections.shuffle(arrayList);
        System.out.println(arrayList);
        //交换
        Collections.swap(arrayList, 0, 1);

        //个数
        int a = Collections.frequency(arrayList, 1);
        System.out.println(a);
        
        //拷贝,注意dest大小应该和原先数组一样
        ArrayList dest = new ArrayList(26);
        for (int i=0; i < arrayList.size(); i++) {
            dest.add("");
        }
        Collections.copy(dest, arrayList);


    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值