Collection集合类分析

时间:2022-10-22 17:03:12

研究问题:

  1. Collection多种类类型:Set(集)、List(列表)、Map(映射)数据存储??

要点:

  • 常用集合类的继承结构如下:
    Collection(接口)<–List(接口)<–Vector
    Collection(接口)<–List(接口)<–ArrayList
    Collection(接口)<–List(接口)<–LinkedList
    Collection(接口)<–Set(接口)<–HashSet(实现类)
    Collection(接口)<–Set(接口)<–HashSet(实现类) <–LinkedHashSet (实现类)
    Collection(接口)<–Set(接口)<–SortedSet(接口)<–TreeSet(实现类)
    Map(接口)<–SortedMap(接口)<–TreeMap(实现类)
    Map(接口)<–HashMap(实现类)
  • Collection
    |–List
    有序(存储顺序和取出顺序一致),可重复
    |–Set
    无序(存储顺序和取出顺序不一致,但它有自己的存储顺序),唯一

    牢记:
    ArrayXxx:底层数据结构是数组,查询快,增删慢
    LinkedXxx:底层数据结构是链表,查询慢,增删快
    HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
    TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

  • HashSet内存图解

Collection集合类分析

  • TreeSet内存图解

Collection集合类分析


截图展示区:

  1. Vector数据存储
    package com.java.Vector;

    import java.util.Enumeration;
    import java.util.Vector;

    /* 容器类 * Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。 * 但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。 * * void addElement(E obj) 将指定的组件添加到此向量的末尾,将其大小增加 1。 * E elementAt(int index) 返回指定索引处的组件。 * Enumeration<E> elements() 返回此向量的组件的枚举。 * * public interface Enumeration<E>实现 Enumeration 接口的对象, * 它生成一系列元素,一次生成一个。连续调用 nextElement 方法将返回一系列的连续元素。 */

    public class VectorDemo {
        public static void main(String[] args) {
            Vector v=new Vector<>();

            v.addElement("hello");
            v.addElement("world");
            v.addElement("java");

            for(int x=0;x<v.size();x++){
                String s=(String) v.elementAt(x);
                System.out.println(s);
            }
            System.out.println("------------");

            //使用枚举进行迭代
            Enumeration en=v.elements();
            while (en.hasMoreElements()) {
                String s = (String) en.nextElement();
                System.out.println(s);
            }

        }
}

Collection集合类分析

2.ArrayList数据存储
  同Vector一样是一个基于数组上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector好一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。
  

package com.java.VariableParameter;

/** * @author FangYang * */
public class Student {
    private String name;
    private int age;
    public Student() {
        super();
    }
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
}
package com.java.VariableParameter;

import java.util.ArrayList;

/*集合的嵌套遍历 * 多种不同ArrayList的遍历,将不同的ArrayList放置于大的ArrayList集合中 */
public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<ArrayList<Student>> bigArrayList=new ArrayList<ArrayList<Student>>();

        //子集合一
        ArrayList<Student> firstArrayList=new ArrayList<Student>();

        Student s1=new Student("唐僧", 30);
        Student s2=new Student("孙悟空", 29);
        Student s3=new Student("猪八戒", 28);
        Student s4=new Student("沙僧", 27);
        Student s5=new Student("白龙马", 26);

        firstArrayList.add(s1);
        firstArrayList.add(s2);
        firstArrayList.add(s3);
        firstArrayList.add(s4);
        firstArrayList.add(s5);

        bigArrayList.add(firstArrayList);

        //子集合二
        ArrayList<Student> secondArrayList=new ArrayList<Student>();

        Student s6=new Student("诸葛亮", 30);
        Student s7=new Student("司马懿", 28);
        Student s8=new Student("周瑜", 26);

        secondArrayList.add(s6);
        secondArrayList.add(s7);
        secondArrayList.add(s8);

        bigArrayList.add(secondArrayList);

        //子集合三
        ArrayList<Student> thirdArrayList=new ArrayList<Student>();

        Student s9=new Student("松江", 40);
        Student s10=new Student("吴用", 35);
        Student s11=new Student("高俅", 30);
        Student s12=new Student("李师师", 22);

        thirdArrayList.add(s9);
        thirdArrayList.add(s10);
        thirdArrayList.add(s11);
        thirdArrayList.add(s12);

        bigArrayList.add(thirdArrayList);

        for(ArrayList<Student> Array:bigArrayList){
            for(Student s:Array){
                System.out.println(s);
            }
        }
    }
}

Collection集合类分析

3. LinkedList(链表)数据存储
  链表不是基于数组的,所以不受数组性能的限制。
它每一个节点(Node)都包含两方面的内容:
  1.节点本身的数据(data);
  2.下一个节点的信息(nextNode)。
所以当对LinkedList做添加,删除动作的时候就不用像基于数组的ArrayList一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了,这是LinkedList的优势。

package com.java.LinkedList;

import java.util.LinkedList;

/* List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。 除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove和 insert元素 提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。 void addFirst(E e) 将指定元素插入此列表的开头。 void addLast(E e) 将指定元素添加到此列表的结尾。 E getFirst() 返回此列表的第一个元素。 E getLast() 返回此列表的最后一个元素。 E removeFirst() 移除并返回此列表的第一个元素。 E removeLast() 移除并返回此列表的最后一个元素。 */

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList link=new LinkedList<>();

        link.add("hello");
        link.add("world");
        link.add("java");

        link.addFirst("android");
        link.addLast("last");

        link.removeFirst();
        link.removeLast();

        System.out.println("link:"+link);

        System.out.println("link.getFirst="+link.getFirst());
        System.out.println("link.getLast="+link.getLast());
    }
}

Collection集合类分析

4.HashSet数据存储
必须同时重写hashCode()和equals()两个方法,才能使相同属性的对象具有相同哈希值。

package com.java.Set;

import java.util.HashSet;

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<Student> hs=new HashSet<Student>();

        Student s1=new Student("林青霞",27);
        Student s2=new Student("柳岩", 22);
        Student s3=new Student("王祖贤", 30);
        Student s4=new Student("林青霞", 20);
        Student s5=new Student("范冰冰", 22);
        Student s6=new Student("林青霞", 27);

        hs.add(s1);
        hs.add(s2);
        hs.add(s3);
        hs.add(s4);
        hs.add(s5);
        hs.add(s6);

        for(Student s:hs){
            System.out.println(s.toString());
        }
    }
}

Collection集合类分析

下接自定义Student类

package com.java.Set;

/* 自然排序 1. 实现TreeSet自然排序,必须实现其Comparable接口,并且实现接口compareTo(T o)方法 2. int compareTo(T o) 3. 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。 */
public class Student implements Comparable<Student>{
    private String name;
    private int age;
    public Student() {
        super();
    }
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }

    //实现LinkedHashSet排序,必须同时重写hashCode()和equals()两个方法,才能使相同属性的对象具有相同哈希值
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public int compareTo(Student o) {
        // TODO 自动生成的方法存根
// return 0;//不排序,怎么进来怎么出去
// return 1;//按从小到大排
// return -1;//按从大到小排

        int num=this.age-o.age;//主要条件
        //次要条件
        int num2=num==0? this.name.compareTo(o.name):num;
        return num2;
    }
}

5. TreeSet数据存储
两种排序方式:A.自然排序。B.比较器排序

package com.java.Set;

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

//按从高到低排序学生总成绩
public class TreeSetDemo4 {
    public static void main(String[] args) {
        TreeSet<Pupil> ts=new TreeSet<Pupil>(new Comparator<Pupil>() {

            //比较器排序
            //使用匿名内部类实现接口的实现类对象
            public int compare(Pupil o1, Pupil o2) {
                // TODO 自动生成的方法存根
                int num=o2.getSum()-o1.getSum();

                int num2=num==0?o1.getChineseScore()-o1.getChineseScore():num;

                int num3=num2==0?o1.getMathScore()-o2.getMathScore():num2;

                int num4=num3==0?o1.getEnglishScore()-o2.getEnglishScore():num3;

                int num5=num4==0?o1.getName().compareTo(o2.getName()):num4;

                return num5;
            }
        });

        Scanner sc=new Scanner(System.in);
        for(int x=1;x<=5;x++){

            System.out.println("输入第"+x+"个学生的姓名:");
            String name=sc.nextLine();
            System.out.println("输入第"+x+"个学生的语文成绩:");
            int ChineseScore=sc.nextInt();
            System.out.println("输入第"+x+"个学生的数学成绩:");
            int MathScore=sc.nextInt();
            System.out.println("输入第"+x+"个学生的英语成绩:");
            int EnglishScore=sc.nextInt();
            sc.nextLine();

            Pupil p=new Pupil(name, ChineseScore, MathScore, EnglishScore);
            /*p.setName(name); p.setChineseScore(ChineseScore); p.setMathScore(MathScore); p.setEnglishScore(EnglishScore);*/
            ts.add(p);
        }

        System.out.println("学生信息从高到底排序:");
        System.out.println("姓名\t语文\t数学\t英语");

        for(Pupil p:ts){
            System.out.println(p.getName()+"\t"+p.getChineseScore()+"\t"+p.getMathScore()+"\t"+p.getEnglishScore());
        }
    }
}

6. HashMap数据存储

package com.java.Map;

import java.util.HashMap;
import java.util.Map;

/* public interface Map<K,V> * 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 * * Map集合概述 * 1.添加功能 * V put(K key, V value)将指定的值与此映射中的指定键关联(可选操作)。 * 2.删除功能 * void clear()从此映射中移除所有映射关系(可选操作)。此调用返回后,该映射将为空。 * V remove(Object key)如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 * 3.判断功能 * boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true。 * boolean containsValue(Object value)如果此映射将一个或多个键映射到指定值,则返回 true。 * 4.获取功能 * Set<Map.Entry<K,V>> entrySet()返回此映射中包含的映射关系的 Set视图。 * V get(Object key)返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 * Set<K> keySet()返回此映射中包含的键的 Set 视图。 * Collection<V> values()返回此映射中包含的值的 Collection 视图。 * 5.长度功能 * int size()返回此映射中的键-值映射关系数。 */

/*public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }
 */
public class MapDemo {
    public static void main(String[] args) {
        Map<String, String> map=new HashMap<String, String>();

//      System.out.println("put:"+map.put("1407010401", "方杨"));

        map.put("1407010402", "周杰伦");
        map.put("1407010403", "张杰");
        map.put("1407010404", "杨幂");
        map.put("1407010405", "金轮法王");

//      map.clear();

        //remove()只能删除键
        /*System.out.println("remove:"+map.remove("1407010403"));
        System.out.println("remove:"+map.remove("杨幂"));
        System.out.println("remove:"+map.remove("赵钱孙李"));*/

        /*System.out.println("containsKey:"+map.containsKey("1407010403"));
        System.out.println("containsKey:"+map.containsKey("1407010401"));*/

        System.out.println("isEmpty:"+map.isEmpty());

        System.out.println("map:"+map);
        System.out.println("size:"+map.size());
    }
}

Collection集合类分析

7.HashMap嵌套型数据存储

package com.java.HashMap;

import java.util.HashMap;
import java.util.Set;

public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<String, HashMap<String, Integer>> hm=new HashMap<String, HashMap<String,Integer>>();

        HashMap<String, Integer> jcMap=new HashMap<String, Integer>();

        jcMap.put("小陈", 20);
        jcMap.put("小高", 22);
        hm.put("jc", jcMap);

        HashMap<String, Integer> jyMap=new HashMap<String, Integer>();

        jyMap.put("小李", 21);
        jyMap.put("小曹", 23);
        hm.put("jy", jyMap);

        Set<String> hmSet=hm.keySet();
        for(String hmKey:hmSet){
            System.out.println(hmKey);
            HashMap<String, Integer> hmValue=hm.get(hmKey);

            Set<String> hmValueSet=hmValue.keySet();
            for(String s:hmValueSet){
                Integer itValue=hmValue.get(s);
                System.out.println("\t"+s+"---"+itValue);
            }
        }
    }
}

Collection集合类分析

8.HashMap-ArrayList数据存储

package com.java.HashMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

/* * HashMap集合元素是ArrayList,有3个 * 每一个ArrayList集合的值是字符串 */
class HashMapIncludeArrayListDemo {
    public static void main(String[] args) {
        HashMap<String, ArrayList<String>> hm=new HashMap<String, ArrayList<String>>();

        ArrayList<String> array1=new ArrayList<String>();
        array1.add("吕布");
        array1.add("周瑜");
        hm.put("三国演义", array1);

        ArrayList<String> array2=new ArrayList<>();
        array2.add("令狐冲");
        array2.add("林平之");
        hm.put("笑傲江湖", array2);

        ArrayList<String> array3=new ArrayList<String>();
        array3.add("郭靖");
        array3.add("杨过");
        hm.put("神雕侠侣", array3);

        Set<String> set=hm.keySet();
        for(String key:set){
            System.out.println(key);
            ArrayList<String> arrayValue=hm.get(key);
            for(String key2:arrayValue){
                System.out.println("\t"+key2);
            }
        }
    }
}

Collection集合类分析

9.ArrayList-HashMap数据存储

package com.java.ArrayList;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class ArrayListIncludeHashMapDemo {
    public static void main(String[] args) {
        ArrayList<HashMap<String, String>> array=new ArrayList<HashMap<String,String>>();

        HashMap<String, String> hm1=new HashMap<String, String>();
        hm1.put("周瑜", "小乔");
        hm1.put("吕布", "貂蝉");
        array.add(hm1);

        HashMap<String, String> hm2=new HashMap<String, String>();
        hm2.put("郭靖", "黄蓉");
        hm2.put("杨过", "小龙女");
        array.add(hm2);

        HashMap<String, String> hm3=new HashMap<String, String>();
        hm3.put("令狐冲", "任盈盈");
        hm3.put("林平之", "岳灵珊");
        array.add(hm3);

        for (HashMap<String, String> hm : array) {
            Set<String> set=hm.keySet();
            for (String key : set) {
                String value=hm.get(key);
                System.out.println(key+"---"+value);
            }
        }
    }
}

Collection集合类分析

10.HashMap-(HashMap-ArrayList)数据存储

package com.java.HashMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class HashMapIncludeHashMap {
    public static void main(String[] args) {
        HashMap<String, HashMap<String, ArrayList<Student>>> hs=new HashMap<String, HashMap<String,ArrayList<Student>>>();
        //Map一:北京校区
        HashMap<String, ArrayList<Student>> hm1=new HashMap<String, ArrayList<Student>>();
        hs.put("北京校区", hm1);

        ArrayList<Student> array1=new ArrayList<Student>();
        hm1.put("基础班", array1);
        Student s1=new Student("林青霞",27);
        Student s2=new Student("风清扬",30);
        array1.add(s1);
        array1.add(s2);

        ArrayList<Student> array2=new ArrayList<Student>();
        hm1.put("就业班", array2);
        Student s3=new Student("赵雅芝",28);
        Student s4=new Student("武鑫鑫",29);
        array2.add(s3);
        array2.add(s4);

        //Map二:上海校区
        HashMap<String, ArrayList<Student>> hm2=new HashMap<String, ArrayList<Student>>();
        hs.put("上海校区", hm2);

        ArrayList<Student> array3=new ArrayList<Student>();
        hm2.put("基础班", array3);
        Student s5=new Student("郭美美",20);
        Student s6=new Student("犀利哥",22);
        array3.add(s5);
        array3.add(s6);

        ArrayList<Student> array4=new ArrayList<Student>();
        hm1.put("就业班", array4);
        Student s7=new Student("罗玉凤",21);
        Student s8=new Student("马征",23);
        array4.add(s7);
        array4.add(s8);

        //Map三:广州校区
        HashMap<String, ArrayList<Student>> hm3=new HashMap<String, ArrayList<Student>>();
        hs.put("上海校区", hm3);

        ArrayList<Student> array5=new ArrayList<Student>();
        hm3.put("基础班", array5);
        Student s9=new Student("王力宏",30);
        Student s10=new Student("李晶磊",32);
        array5.add(s9);
        array5.add(s10);

        ArrayList<Student> array6=new ArrayList<Student>();
        hm3.put("就业班", array6);
        Student s11=new Student("郎朗",31);
        Student s12=new Student("柳岩",33);
        array6.add(s11);
        array6.add(s12);

        //Map四:西安校区
        HashMap<String, ArrayList<Student>> hm4=new HashMap<String, ArrayList<Student>>();
        hs.put("西安校区", hm4);

        ArrayList<Student> array7=new ArrayList<Student>();
        hm4.put("基础班", array7);
        Student s13=new Student("范冰冰",30);
        Student s14=new Student("刘意",32);
        array7.add(s13);
        array7.add(s14);

        ArrayList<Student> array8=new ArrayList<Student>();
        hm4.put("就业班", array8);
        Student s15=new Student("李冰冰",28);
        Student s16=new Student("张志豪",29);
        array8.add(s15);
        array8.add(s16);


        Set<String> set=hs.keySet();
        for(String hsKey:set){
            System.out.println(hsKey);
            HashMap<String, ArrayList<Student>> hsValue=hs.get(hsKey);

            Set<String> hsValueSet=hsValue.keySet();
            for(String hsValueKey:hsValueSet){
                System.out.println("\t"+hsValueKey);
                ArrayList<Student> arraylist=hsValue.get(hsValueKey);

                for(Student s:arraylist){
                    System.out.println("\t\t"+s.getName()+"---"+s.getAge());
                }
            }
        }
    }
}

Collection集合类分析

11.TreeMap数据存储

package com.java.TreeMap;

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

public class TreeMapDemo2 {
    public static void main(String[] args) {
        TreeMap<Student, String> tm=new TreeMap<Student, String>(new Comparator<Student>() {

            @Override
            public int compare(Student o1, Student o2) {
                // TODO 自动生成的方法存根
                int num=o1.getAge()-o2.getAge();
                int num2=num==0?o1.getName().compareTo(o2.getName()):num;
                return num2;
            }
        });

        Student s1=new Student("潘安",30);
        Student s2=new Student("柳下惠",35);
        Student s3=new Student("唐伯虎",33);
        Student s4=new Student("燕青",32);
        Student s5=new Student("唐伯虎",33);

        tm.put(s1, "宋");
        tm.put(s2, "元");
        tm.put(s3, "明");
        tm.put(s4, "清");
        tm.put(s5, "汉");

        Set<Student> set=tm.keySet();
        for (Student s:set) {
            String value=tm.get(s);
            System.out.println(s.getName()+"---"+s.getAge()+"---"+value);
        }
    }
}

Collection集合类分析