javaSE中集合的相关知识

目录

有关集合的体系图

Collection 接口的讲解

接口的常用实现方法(增删改查)

Collection接口的Iterator(迭代器)遍历元素

 用增强for循环遍历元素(可以用于集合也可用于数组)

有关list接口特点和常用语法

有关ArrayList底层结构和源码分析

注意事项

源码分析

有关Vector底层结构和源码分析

基本介绍

源码分析

有关LinkList底层结构

 LinkList的全面说明

LinkedList的底层操作机制

ArrayList和LinkedList比较

set接口和常用方法

set接口的基本介绍

set接口的常用方法

set接口的遍历方式

HashSet的全面说明

链表底层机制说明

添加元素底层的实现

set的接口实现类-LinkedHashSet

LinkedHashSet的全面说明

LinkedHashSet添加的元素顺序

有关Map的体系图


有关集合的体系图

Iterable 可迭代

Collection 集合

Vector 向量

Collection 接口的讲解

1)Collection实现的子类可以存放多个元素,每个元素可以是Object

2)Collection实现的子类,有些可以存放相同的元素,有些不能存放相同的元素

List可以存放相同的元素,Set不可以存放相同的元素

3)Collection实现的子类,有些是有序的(List),有些是无序的(Set)

4)Collection没有直接实现的子类,是通过他的子接口List来实现的

接口的常用实现方法(增删改查)

package practice2;

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

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list = new ArrayList<>();
        //1.add:添加单个元素  addAll:添加所选集合元素
        list.add("hlk");
        list.add(123);
        list.add(true);
        System.out.println(list);// [hlk, 123, true]
        List list1 = new ArrayList();
        list1.add("nihao");
        list1.add(12);
        list.addAll(list1);
        System.out.println(list);//[hlk, 123, true, nihao, 12]
        // 2.remove: 删除指定元素,可以选择序号。也可以选择指定的内容 removeAll删除所选集合的元素
        list.remove(0);
        System.out.println(list);// [123, true, nihao, 12]
        list.removeAll(list1);
        System.out.println(list);//[123, true]
        //3.contains:查找元素是否存在 containAll:查看集合里面有没有所选的集合
        System.out.println(list.contains(123));//true
        System.out.println(list.containsAll(list1));//false
        //4.size:获取元素的个数
        System.out.println(list.size());//2
        //5.isEmpty:判断是否为空
        System.out.println(list.isEmpty());//false
        //6.clear 清空所有的元素
        list.clear();
        System.out.println(list);//[]
    }
}

Collection接口的Iterator(迭代器)遍历元素

1)Iterator对象成为迭代器,主要用于遍历Collection集合中的元素

2)所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器。

3)参考Iterator的结构图

在调用Iterator.next方法的前面必须调用iterator.hasnext()进行检测,如果不调用会出现异常

4)Iterator仅用于遍历集合,Iterator本身并不存放对象

Iterator迭代器的代码实现(快捷键itit)

package practice2;

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

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        Collection collection = new ArrayList();
        collection.add(new Book("西游记",13));
        collection.add(new Book("红楼梦",14));
        collection.add(new Book("三国演义",15));
        collection.add(new Book("水浒传",16));
        //1.先得到col对应的迭代器
        Iterator iterator = collection.iterator();
        //2.使用while循环遍历
        while (iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println(obj);
            //Book{name='西游记', price=13.0}
            //Book{name='红楼梦', price=14.0}
            //Book{name='三国演义', price=15.0}
            //Book{name='水浒传', price=16.0}
        }
        //3.退出while循环后,这时iterator迭代器,指向最后的元素,然后会报错
        //4.如果希望再次遍历,需要重置我们的迭代器
        iterator = collection.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
            //Book{name='西游记', price=13.0}
            //Book{name='红楼梦', price=14.0}
            //Book{name='三国演义', price=15.0}
            //Book{name='水浒传', price=16.0}
        }
    }
}
class Book{
     private String name;
     private double price;

    public Book(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

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

 用增强for循环遍历元素(可以用于集合也可用于数组)

使用增强for循环也可以做到像迭代器那样的遍历元素

1)使用增强for,在collection集合

2)使用增强for,底层仍然是迭代器

3)增强for可以理解成就是简化版本的 迭代器遍历

4)快捷键方式 I

代码实现展示

package practice2;

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

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        Collection collection = new ArrayList();
        collection.add(new Book("西游记",13));
        collection.add(new Book("红楼梦",14));
        collection.add(new Book("三国演义",15));
        collection.add(new Book("水浒传",16));

        for(Object obj : collection){
            System.out.println(obj);
        }
        
        int[] nums = {1,2,3,4,5};
        for(int i : nums){
            System.out.println(i);
        }
        

    }
}

有关list接口特点和常用语法

特点

1)list集合类中元素有序(即添加顺序和取出顺序一致),且可重复

2)List集合中的每个元素都有其对应的顺序索引,即支持索引,从零开始

3)JDK API中list接口的实现类,常用的有Arraylist,LinkList,Vector

用代码展示


public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        //1:list集合类中元素有序(即添加顺序和取出顺序一致),且可重复
        List list = new ArrayList();
        list.add(123);
        list.add("xiMing");
        list.add("hlk");
        System.out.println(list);//[123, xiMing, hlk]
        //2:List集合中的每个元素都有其对应的顺序索引,即支持索引,从零开始
        System.out.println(list.get(1));//xiMing

    }
}

常用语法

package practice2;

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

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("张三丰");
        list.add("贾宝玉");
        //1:void add(int index, Object ele):在index位置插入ele元素
        //如果没有写那么默认加入在最后一个
        list.add(1,"hsp");
        System.out.println(list);//[张三丰, hsp, 贾宝玉]
        //2:void addAll(int index, Collection eles):从index位置开始将eles中的所有元素位置加进来
        List list1 = new ArrayList();
        list1.add(123);
        list1.add("nb");
        list.addAll(1,list1);
        System.out.println(list);// [张三丰, 123, nb, hsp, 贾宝玉]
        //3:Object get(int index ):返回指定index位置的元素
        System.out.println(list.get(1));// 123
        list.add(123);
        //4:int indexOf(Object obj):返回obj在当前集合中首次出现的位置
        //5:int lastIndexOf(Object obj):返回obj在当前集合中出现的最后位置
        System.out.println(list.indexOf("nb"));//2
        System.out.println(list.lastIndexOf(123));//5
        //6:remove移除第几个或者具体的元素
        list.remove("nb");
        list.remove(1);
        System.out.println(list);// [张三丰, hsp, 贾宝玉, 123]
        //7:Object set(int index , Object ele) 相当于替换掉所选中的元素
        list.set(3,12345);
        System.out.println(list);// [张三丰, hsp, 贾宝玉, 12345]
        //8.List subList(int fromIndex, int toIndex)返回从fromIndex到toIndex位置的子集合,前闭后开
        list.subList(0,2);//实际返回的就是0和1号元素
        System.out.println(list.subList(0,2));
    }
}

list的三种遍历方式

1)迭代器

2)增强for

3)普通for、

package practice2;

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

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        //list接口的实现子类Vector LinkedList
        List list = new ArrayList();
        list.add(123);
        list.add(123);
        list.add(123);
        //1.遍历
        // 迭代器
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
        //2.增强for循环
        for (Object o : list) {
            System.out.println(o);
        }
        //3.使用普通for
        for (int i = 0; i < list.size() ;i++) {
            System.out.println(list.get(i));
        }

    }
}

有关ArrayList底层结构和源码分析

注意事项

1)ArrayList可以加入null,并且多个

2)ArrayList是由数组来实现数据存储的

3)ArrayList基本等同于Vector,除了ArrayList是线程不安全,在多线程的时候用Vector

源码分析

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

transient Object[] elementData (用的Object 所以所有的元素都可以放)

transient表示瞬间的,短暂的,表示改属性不会被序列号

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

3)如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。

有关Vector底层结构和源码分析

基本介绍

1)定义类的说明

 2)Vector底层也是一个对象数组,protected Object[] elementData

3)Vector是线程同步的,即线程安全,Vector类的操作方法都有synchronized

4)在开发中需要线程同步安全是,考虑使用Vector

源码分析

Vector和ArrayList的比较

有关LinkList底层结构

 LinkList的全面说明

1)LinkList底层实现饿了双向链表和双端队列的特点

2)可以添加任意元素(元素可以重复),包括null

3)线程不安全,没有实现线程同步

LinkedList的底层操作机制

1)LinkedList底层维护了一个双向链表

2)LinkedList中维护了两个属性first和last分别指向 首节点和尾节点

3)每个节点(Node对象),里面又维护了prev,next,item三个属性,期中通过prev指向前一个,通过next指向后一个节点,最终实现双向链表 

4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高

ArrayList和LinkedList比较

如何选择ArrayList和LinkedList

1)如果我们的改查的操作多,选择ArrayList

2)如果我们的增删操作多,选择LinkedList

3)一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList

4)在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另一个模块使用的是LinkedList,也就是说,药根据业务来进行选择

set接口和常用方法

set接口的基本介绍

1)无序(增加和取出的顺序不一致),没有索引

2)不允许重复元素,所以最多包含一个null

3)JDK API 中Set接口的实现类有:

set接口的常用方法

和List接口一样,Set接口也是Collection的子接口,因此常用方法和Collection一样

set接口的遍历方式

同Collection的遍历方式一样,因为Set接口是Collection接口的子接口

1)可以使用迭代器

2)增强for

3)不能使用索引的方式来获取

HashSet的全面说明

1)HashSet实现了Set接口

2)HashSet实际上是HashMap

3)可以存放null值,但是只能存放一个

4)HashSet不保证元素是有序的,没取决于hash后,再确定索引的结果

5)不能有重复元素/对象,再前面Set接口使用已经讲过

链表底层机制说明

分析HashSet底层是HashMap,HashMap底层是(数组+链表+红黑树)

模拟下简单的数组和链表结构

package practice2;

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        //模拟一个HashSet的底层(HashMap的底层结构)
        //1:创建一个数组,数组的类型是Node[]
        //2:有些人,直接把Node[]数组称为表
        Node[] table = new Node[16];
        System.out.println(table);
        //3.创建结点
        Node john = new Node("john",null);
        table[2] = john;
        Node jack = new Node("jack",null);
        john.next = jack;
        Node Rose = new Node("Rose",null);
        jack.next = Rose;
        


    }
}
class Node{//结点,存储数据,可以指向下一个结点,从而形成链表
    Object item;//存放数据
    Node next;//指向下一个结点

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

添加元素底层的实现

1)Hash底层是HashMap,第一次添加时,table数组扩容到16,临界值是16 ,加载因子就是0.75*16 =12 ,当里面的数组内容加到12的时候,就会扩容到16*2 =32依此类推

2)添加一个元素时,先得到hash值 -会转成 ->索引值

3)找到存储数据表table,看这个索引位置是否已经存放的铀元素

4)如果没有,直接加入

5)如果有,调用equals比较,如果相同,就放弃添加,如果不相同,则添加再最后

6)在Java8中,如果一条链表的元素个数到达8,且table大小>=64就会进行树化

package practice2;

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

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add(new Dog(13,"hlk"));
        hashSet.add(new Dog(13,"hlk"));
        System.out.println(hashSet);
    }
}
class Dog{
    private int age;
    private String name;

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

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

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

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

LinkedHashSet的解读

LinkedHashSet的全面说明

1)LinkedHashSet是HashSet的子类

2)LinkedHashSet底层是一个LinkedHashMap,底层维护了一个数组+双向链表

3)LinkedHashSet是根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

4)LinkedHashSet不允许添加重复元素

LinkedHashSet添加的元素顺序

主要看韩老师的这个图理解LinkedHashSet的图的元素添加顺序

 和HashSet的最大优点就是有顺序,遍历顺序一致

有关Map的体系图

Properties 性能,属性

Map接口和常用方法

Map接口特点(有点像python中的字典)

1)Map与Collection并列存在。用于保存具有映射关系的数据Key - Value(双列元素)

2)Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中

3)Map中的 key 不允许重复,原因和HashSet一样(因为hashcode一样,放一样的位置)

如果key值重复了,那么后面的值会代替掉前面的值

4)Map中的 value是可以重复的

5)Map中的key可以为null,value也可以为null,Map中的key只能有一个null,但是value可以有多个null

6)常用String类作为Map的key

形象一点的Map图

Map存放数据的key - vlaue示意图,一队k - v是放在一个HashMapNode中的,有因为Node实现了,Entry接口,有些书上也说一对k-v就是一个Entry

Map接口和常用方法

1)put:添加

2)remove:根据键删除映射关系

3)get:根据键获得值

4)sieze:获取元素个数

5)isEmpty:判断元素个数是否为0

6)containKey:查找键是否存在

//这个算是小儿科了,我就不放代码了,和之前的都差不多的

Map接口的遍历6种形式

1)containsKey:查找键是否存在

2)keySet获取所有的键

3)entrySet获取所有关系的k -y

4)values获取所有的值

package practice2;


import java.util.*;

public class Test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        //演示map接口的常用方法
        Map map = new HashMap();
        map.put("邓超","孙俪");
        map.put("王宝强","马蓉");
        map.put("宋吉","马蓉");
        //1.第一种使用keyset来判断
        //(1)增强for
        Set keyset = map.keySet();
        for (Object key : keyset) {
            System.out.println(key+ "-" + map.get(key));
        }
        //(2)迭代器
        System.out.println("------------------------");
        Iterator iterator = keyset.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key + "--"+ map.get(key));
        }
        System.out.println("----------");


        //2.第二种是把所有的values取出
        Collection values = map.values();
        //(1)增强for
        for (Object value : values) {
            System.out.println(value);
        }
        //(2)迭代器
        System.out.println("-----------");

        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()) {
            Object value =  iterator1.next();
            System.out.println(value);
        }
        //3.通过EntrySet来获取来获取key - value
        System.out.println("-----------");
        Set entrySet = map.entrySet();
        //(1)增强for
        for (Object entry :entrySet) {
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "--" +m.getValue());
        }
        //(2)迭代器
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Object entry =  iterator2.next();
            Map.Entry Entry = (Map.Entry) entry;
            System.out.println(Entry.getKey()+"--"+Entry.getValue());
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值