基础集合概述

集合

1.类集关系图

在这里插入图片描述

2.集合框架概述

    1、集合类的出现:面向对象语言对事物的体现的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

    2、数组与集合的异同:数组和集合同是容器,数组既能存储基本数据类型,也能存储对象,集合只能存储对象,数组的长度是固定的,集合的长度是可变的,数组内存储的对象类型在创建时就已经确定了,而集合可以存储多种不同类对象。

    3、集合类中有众多的子类对象,它们作为容器对数据的存储方式都不同,这种方式叫做数据结构。

3.集合运用场景


        List:  ArrayList和LinkedList
         ArrayList:底层实现原理是数组,LinkedList:链表  数组遍历快,LinkedList增删元素块:
                遍历的需求比增删除多,添加元素只是在末尾添加
               遍历集合中的元素比较多
        set:HashSet TreeSet LinkedHashSet
                需要保证集合中的元素是唯一性,就用ser集合:
                一批消息给用户,避免一次发送重复的内容,使用set集合?
                    保证添加的用户不能有重复,使用HashSet添加删除查询··TreeSet排序,后期数据库中可以把数据有序的输出
                     order by(数据库排序)
                  HashSet:一个没有重复元素的集合(去除重复元素)
                  LinkedHashSet和TreeSet:用作于算法题
        Map:HashMap,linkedHashMp TreeMap
            工作只要存储key-valueL选用HashMap
               ConcurrentHashMap:挺多的,用作于本地缓冲:不想每次都需要网路请求数据,在本地做本地缓存文件,监听数据的变量,如果数据变动
               对于的值给更新
               LinkedHashMap和Treemap在开发中用的不多,当做刷算法题

一、Collection集合类(单值存储)

2.ArrayList

1.对于增加删除慢,查找快。
2.ArrayLisr<Integer> date = new ArrarList();
·泛型的类型必须是包装类
        //arrayList.ensureCapacity(14);//指定数组长度
        arrayList.trimToSize();//将此 ArrayList实例的容量调整为列表的当前大小
        arrayList.add('A');
        arrayList.add("B");
        arrayList.add(9);
        arrayList.add("哈哈");
        arrayList.add('A');
        arrayList.add("B");
        arrayList.add(9);
        arrayList.add('A');
        arrayList.add("B");
        arrayList.add(9);
        arrayList.add("哈哈");
        arrayList.add('A');
        arrayList.add("B");
        arrayList.add(9);
        //arrayList.removeAll(arrayList);//移除arrayList这个集合中所有元素
//        arrayList.clear();//清除数组中所有元素
        arrayList.clone();
       for (Object arr:arrayList){
           System.out.print(arr+" ");
       }
        System.out.println(arrayList.contains("B"));//查找数组中是否包含“B”;
        System.out.println(arrayList.indexOf(9));//查找数据在数组中第一个出现的位置,如果没有则返回-1
        System.out.println(arrayList.isEmpty());//数组为空返回true,反之为false
        System.out.println(arrayList.iterator().next());
        System.out.println(arrayList.lastIndexOf("哈哈"));//最后一次出现的位置
        System.out.println(arrayList.listIterator(9));//返回当前迭代器(地址)
        System.out.println(arrayList.listIterator(10).next());//返回当前迭代器地址对应的元素值
        Object[] sc=arrayList.toArray();//以适当的顺序(从第一个元素到最后一个元素)返回包含此列表中所有元素的数组。
        for (Object ac:sc){
            System.out.print(ac+" ");//变为了数组
        }
        System.out.println();
        System.out.println(arrayList.subList(2,10));//输出[9, 哈哈, A, B, 9, A, B, 9]
    }

3.Vector(使用方法和ArrayList相差不多,具体看API文档)

4.LinkedList

使用的是双向链表结构,对于增删快,查找满
 LinkedList<Integer> date=new LinkedList<>();
        date.add(1);
        date.add(2);
        date.add(3);
        //date.addFirst(3);//放在第一个
        System.out.println(date);
        Integer i= date.removeFirst();//取出第一个
        System.out.println(i);

        //压栈
        date.push(100);
        date.push(200);
        //弹栈
        Integer ii=date.pop();
        System.out.println(ii);//先进后出
    }
}

5.Iterator和ListIterator

5.1迭代器

迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

  Java中的Iterator功能比较简单,并且只能单向移动:

  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

  (2) 使用next()获得序列中的下一个元素。

  (3) 使用hasNext()检查序列中是否还有元素。

  (4) 使用remove()将迭代器新返回的元素删除。
调用方法,得到的迭代器行为类似指针的对象,(迭代器是抽象的)
例子:
        ArrayList<Integer> date=new ArrayList<>();
        date.add(1);
        date.add(2);
        date.add(3);
        date.add(4);
        //输出集合的内容可以不用循环遍历,用迭代器
//        Iterator<Integer> integer=date.iterator();//获得date的地址
//        while (integer.hasNext()==true){//判断integer是否有下一个数据
//            System.out.println(integer.next());//如果判断有下一个数据,就直接输出下一个数据。
//            //需要注意的是,指针最开始指的是第一个数的上面位置,它的下一个数据就是第一个数据
//        }
//        integer.remove();//将迭代器新返回的元素删除(先进后出)
//        System.out.println("["+date.size()+"]");
//        System.out.println("------------------");
//        for (int i = 0; i < date.size(); i++) {
//            System.out.println(date.get(i));
//        }

        ListIterator<Integer>  iterator=date.listIterator();
        iterator.add(100);//添加在1的前面;
        iterator.next();
        iterator.next();
        iterator.set(200);//指针向下移两次,把2变成200

        iterator.previous();
        iterator.previous();
        iterator.previous();//向上移动迭代器三次才能遍历全部数据
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

6.forEach

6.1作用

1,增强For循环
2,只能用于迭代数组,或集合(Collection)

6.2语法

语法:
   for(数据类型  变量名:集合或数组名){}

二.set(不保证顺序)

set集合是使用Map集合的 键 来存储的数据,值是后台使用的统一值、
保证集合中元素的唯一性
Hashset:一般用于增加删除查询
TreeSet:一般用于排序

2.1Hashset

2.1.1请简述 HashSet 去除重复元素的原理
A:HashSet底层数据结构是哈希表(是一个元素为链表的数组) 

B:哈希表底层依赖两个方法:hashCode()和equals()
执行顺序:

    首先比较哈希值是否相同

        相同:继续执行equals()方法
        
               返回true:元素重复了,不添加
               返回false:直接把元素添加到集合
               
        不同:就直接把元素添加到集合
C:元素唯一性由hashCode()和equals()保证的,二者缺一不可

1-hashSet属于set的子类,是属于set的实现类
2-hashSet是散列存放,所以不能按正常的顺序输出,并且不能存储相同的值。

        HashSet<String> hashSet=new HashSet<>();
        hashSet.add("床前明月光");
        hashSet.add("疑是地上霜");
        hashSet.add("举头望明月");
        hashSet.add("低头思故乡");
        Iterator<String> iterator=hashSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());//散装输出,即不按照顺序输出
        }
结果:
举头望明月
床前明月光
疑是地上霜
低头思故乡

2.3TreeSet

1-是利用有序的二叉树存储(有序的存放)
例子:
        //存储有序是根据数据的顺序,而不是你存入的顺序
        TreeSet<String> date=new TreeSet<>();
        date.add("B");
        date.add("C");
        date.add("A");
        date.add("D");
        for (String s:date){
            System.out.println(s);
        }
输出:A   B  C  D
2-此类的iterator方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时间修改集合,除了自己的remove方法之外,迭代器将抛出ConcurrentModificationException异常(一般都是安全失败的)除了特殊声明外的。
2.3.1Comparable
如果TreeSet存入的是系统不能比较的内容,这时候我们就需要用该类来实现comparable接口,然后重写comparable的抽象方法,以此来比较输入的类容
注意:如果存入一样大的数据,就不会存储
如:    TreeSet<Person>  date = new TreeSet<>();
        Person p1 = new Person("张三",12);
        Person p2 = new Person("李四",19);
        date.add(p1);
        date.add(p2);

        for (Person p:date){
            System.out.println(p.toString());
        }
    }
}
class Person implements Comparable<Person>{//必须实现Comparable接口,然后自己在抽象方法重写比较内容
    private String name;
    private int age;
    @Override
    public int compareTo(Person o) {//第一次的值直接传入,第二次的值和第一次比较在传入
        //this 与  o比较
        //返回值:正数this大、负数this小、0相等
        if (this.age>o.age){
            return 1;
        }else if (this.age<o.age){
            return -1;
        }else {
            return 0;
        }
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
2.3.2简述 Comparable 和 Comparator 两个接口的区别
Comparable和Comparator都是用来实现集合中元素的比较、排序的。

Comparable是在集合内部定义的方法实现的排序,位于java.lang下。

Comparator是在集合外部实现的排序,位于java.util>下。Comparable是一个对象本身就已经支持自比较所需要实现的接口,如String、Integer自己就实现了Comparable接口,可完成比较大小操作。自定义类要在加入list容器中后能够排序,也可以实现Comparable接口,在用Collections类的sort方法排序时若不指定Comparator,那就以自然顺序排序。所谓自然顺序就是实现Comparable接口设定的排序方式。

Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。Comparatorl类体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。总而言之Comparable是自已完成比较,Comparator是外部程序实现比较。

三、Map

Map集合存储的是一个个的 键值对 的数据
Map集合的 键 不能重复,一个键对应一个值
Map<K V>泛型指定一个键的类型,一个值得类型

Map集合存入数据遍历输出的方法:
首先用 KeySet 取出键值、它属于Set类型,然后遍历Key,然后用 get(Object Key)获取值


Map集合存入数据:
Put(K key,V value) 如果存储数据时,key已经有对应的值,那么新值替换旧值,然后返回旧值,如果没有对应的值,则返回null

1.HashCode(Object)

-计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类Object的hashCode()方法的计算依赖于对象实例的D(内存地址),故每个Object对象的hashCode都是唯一的;当然,当对象所对应的类重写了hashCode()方法时,结果就截然不同了。

-Java对象的eqauls方法和hashCode方法是这样规定的:

1、相等(相同)的对象必须具有相等的哈希码(或者散列码)。
原因 :
想象一下,假如两个Java对象A和B,A和B相等(eqauls结果为true),但A和B的哈希码不同,则A和B存入HashMap时的哈希码计算得到的HashMap内部数组位置索引可能不同,那么A和B很有可能允许同时存入HashMap,显然相等/相同的元素是不允许同时存入HashMap,HashMap不允许存放重复元素。

2、如果两个对象的hashCode相同,它们并不一定相同。
原因:
也就是说,不同对象的hashCode可能相同;假如两个Java对象A和B,A和B不相等(eqauls结果为false),但A和B的哈希码相等,将A和B都存入HashMap时会发生哈希冲突,也就是A和B存放在HashMap内部数组的位置索引相同这时HashMap会在该位置建立一个链接表,将A和B串起来放在该位置,显然,该情况不违反HashMap的使用原则,是允许的。当然,哈希冲突越少越好,尽量采用好的哈希算法以避免哈希冲突。

2.HashMap

1.HashMap概述:

HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

2.HashMap的数据结构:

HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。首先,HashMap类的属性中定义了Entry类型的数组。Entry类实现java.ultil.Map.Entry接口,同时每一对key和value是作为Entry类的属性被包装在Entry的类中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rnHtfgjO-1594040160846)(D:\kaikeba\任务卡提交作业\第四章核心类库训练\集合(4-3)\0611-尹智辉-集合-2020-7-5\图片\哈希表)]

散列因子是指(负载因子):当75%哈希桶的被装了数据时,哈希桶就会进行二倍扩容

3.HashMap代码实现

        //hashMap(顺序)/Hashtable(和HashMap执行顺序不同,倒叙)/ConcurrentHashMap
        //TreeMap
        //LinkedHashMap
        //以上用法一样
        HashMap<Integer,String> date=new HashMap<>();
        date.put(1,"A");
        date.put(2,"B");
        date.put(3,"C");
        date.put(4,"D");
        String key=date.get(1);
        System.out.println(key);//输出A
        Set<Integer> set=date.keySet();//取出键,转成set集合
        for (Integer in:set){
            System.out.println(in+"->"+date.get(in));
        }
        Collection<String> values=date.values();//变为Collection集合
        for(String value: values){
            System.out.println(value);//只有值
        }

3.哈希值

哈希值就是文件的身份证,不过比身份证还严格。他是根据文件大小,时间,类型,创作着,机器等计算出来的,很容易就会发生变化,谁也不能预料下一个号码是多少,也没有更改他的软件。

注意:所以不能存在键的位置,键是获取哈希值的位置,当你把自定义对象内容存在键时就不易更改了,除非你存在其他地方

四、Java中 List、Set、Map 之间的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rrm0u5Af-1594040160848)(D:\kaikeba\任务卡提交作业\第四章核心类库训练\集合(4-3)\0611-尹智辉-集合-2020-7-5\图片\区别.png)]

1.list(列表)

List的元素以线性方式存储,可以存放重复对象,List主要有以下两个实现类:

ArrayList : 长度可变的数组,可以对元素进行随机的访问,向ArrayList中插入与删除元素的速度慢。 JDK8 中ArrayList扩容的实现是通过grow()方法里使用语句newCapacity = oldCapacity + (oldCapacity >> 1)(即1.5倍扩容)计算容量,然后调用Arrays.copyof()方法进行对原数组进行复制。
LinkedList: 采用链表数据结构,插入和删除速度快,但访问速度慢。

2.Set(集合)

Set中的对象不按特定(HashCode)的方式排序,并且没有重复对象,Set主要有以下两个实现类:


HashSet: HashSet按照哈希算法来存取集合中的对象,存取速度比较快。当HashSet中的元素个数超过数组大小*loadFactor(默认值为0.75)时,就会进行近似两倍扩容(newCapacity = (oldCapacity << 1) + 1)。

TreeSet :TreeSet实现了SortedSet接口,能够对集合中的对象进行排序。

3.Map(映射)

Map是一种把键对象和值对象映射的集合,它的每一个元素都包含一个键对象和值对象。 Map主要有以下两个实现类:


HashMap:HashMap基于散列表实现,其插入和查询<K,V>的开销是固定的,可以通过构造器设置容量和负载因子来调整容器的性能。 

LinkedHashMap:类似于HashMap,但是迭代遍历它时,取得<K,V>的顺序是其插入次序,或者是最近最少使用(LRU)的次序。

TreeMap:TreeMap基于红黑树实现。查看<K,V>时,它们会被排序。TreeMap是唯一的带有subMap()方法的Map,subMap()可以返回一个子树。

4.存储特点

一丶存放
List存放元素是有序,可重复
Set存放元素无序,不可重复
Map元素键值对形式存放,键无序不可重复,值可重复
二丶取出
List取出元素for循环,foreach循环,Iterator迭代器迭代
Set取出元素foreach循环,Iterator迭代器迭代
Map取出元素需转换为Set,然后进行Iterator迭代器迭代,或转换为Entry对象进行Iterator迭代器迭代

散列表实现,其插入和查询<K,V>的开销是固定的,可以通过构造器设置容量和负载因子来调整容器的性能。

LinkedHashMap:类似于HashMap,但是迭代遍历它时,取得<K,V>的顺序是其插入次序,或者是最近最少使用(LRU)的次序。

TreeMap:TreeMap基于红黑树实现。查看<K,V>时,它们会被排序。TreeMap是唯一的带有subMap()方法的Map,subMap()可以返回一个子树。


## 4.存储特点

一丶存放
List存放元素是有序,可重复
Set存放元素无序,不可重复
Map元素键值对形式存放,键无序不可重复,值可重复
二丶取出
List取出元素for循环,foreach循环,Iterator迭代器迭代
Set取出元素foreach循环,Iterator迭代器迭代
Map取出元素需转换为Set,然后进行Iterator迭代器迭代,或转换为Entry对象进行Iterator迭代器迭代


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值