java 集合详细解析 List接口 Set接口 map接口

目录

List接口概述:

List实现类之一:ArrayList

单例 (Singleton)设计模式

单例(Singleton)设计模式-懒汉式

说到懒汉式的线程安全方式:

List接口的理解:

List接口方法:

List实现类之二:LinkedList

新增方法:

List 实现类之三:Vector

List总结一下:

Collection子接口之二:Set接口

总结:

Set实现类之一:HashSet

这文章里边有单独的说明hashset

Set实现类之二:LinkedHashSet

Set实现类之三:TreeSet

理解:

自然排序:

排序—定制排序:

 *一Map接口

 Map接口概述:

hashMap底层:数组 加 链表 jdk7数组 加 链表 加 红黑树  jdk8

二:Map机制的理解:

三Hashmap的底层实现原理:

Map接口:常用方法

结果1

Map实现类之二:LinkedHashMap

Map实现类之三:TreeMap

Properties 类

Collections工具类:


List接口概述:

鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组,我们一般说的动态数组。

 List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。

List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据 序号存取容器中的元素。

JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。

List实现类之一:ArrayList

ArrayList 是 List 接口的典型实现类、主要实现类

本质上,ArrayList是对象引用的一个”变长”数组

ArrayList的JDK1.8之前与之后的实现区别?

 JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组

 JDK1.8:ArrayList像懒汉式,一开始创建一个长度为0的数组,当添加第一个元 素时再创建一个始容量为10的数组

Arrays.asList(…) 方法返回的 List 集合,既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合

java 集合详细解析 List接口 Set接口 map接口_第1张图片

单例 (Singleton)设计模式

设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、 以及解决问题的思考方式。设计模免去我们自己再思考和摸索。就像是经典 的棋谱,不同的棋局,我们用不同的棋谱。”套路”

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。 如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象, 静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象 的变量也必须定义成静态的。

单例(Singleton)设计模式-饿汉式

class Singleton { // 1.私有化构造器

private Singleton() { }

// 2.内部提供一个当前类的实例

// 4.此实例也必须静态化 private static Singleton single = new Singleton();

// 3.提供公共的静态的方法,返回当前类的对象

public static Singleton getInstance() {

return single; } }

单例(Singleton)设计模式-懒汉式

class Singleton {

// 1.私有化构造器 private Singleton() { }

// 2.内部提供一个当前类的实例

// 4.此实例也必须静态化

private static Singleton single;

// 3.提供公共的静态的方法,返回当前类的对象

public static Singleton getInstance() {

if(single == null)

{

single = new Singleton();

} return single;

}

}

说到懒汉式的线程安全方式:

加个线程安全的同步监视器,让这个单例的懒汉式线程更加安全:

public class danli {

}
class Bank{
    private Bank(){

    }
    private static Bank instance=null;
    public static Bank getInstance() {


//        synchronized (Bank.class) {//效率低
//            if (instance==null){
//                instance=new Bank();
//
//            }
//        }
//        return instance;
//
//    }
        if (instance == null) {//效率高 立个牌子告诉后来线程不能过来,直接出去
            synchronized (Bank.class) {
                if (instance == null) {
                    instance = new Bank();

                }
            }


        }
        return instance;
    }
}

List接口的理解:

list接口 有序的可重复 动态数组 替换原有的数组
*  ArrayList
*  Linkedlist
*  vector  早于list接口出现了一般不使用
*  它们之间的异同点
*  相同:都是实现list接口的实现类而出现的 都实现了list接口
*  存储数据特点相同
*  不同点:
*  1.ArrayList 作为list接口的主要实现类 数组底层Object[]顺序的结构
*  2.ArrAyList 删除数据 需要覆盖的方式 后边的数据向前移动 插入元素需要往后移动 效率低
*  3.vector 作为list接口出现的古老实现类jdk出現最早,比是实现接口list还早
*  4. Arraylist 是一个线程不安全的但是效率高
*  5.vector 是一个线程安全的 同步 效率差点
*  6.底层Arraylist 底层使用的是Object 中数组的存储结构 Object []elementData
*  7. LinkedList 底层使用的是双向存储的链表 对于频繁的插入和删除操作 效率比较高
*  8.双向链表的方式存储 删除一个元素 前一个元素的next地址给下一个元素地址 下一个元素的地址指向上一个元素的地址
*  双向链表没有数组 是数据结构中的一个数据存储
*9.常用方法
* 增:add();末尾添加
* 删:remove(Index) remove(obj)
* 改:set(index ele)
* 查:get(index)
* 插:add(int index ,object obj)
* 长度:size()

List接口方法:

List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来 操作集合元素的方法。 1.void add(int index, Object ele):在index位置插入ele元素

2.boolean addAll(int index, Collection eles):从index位置开始将eles中 的所有元素添加进来

3.Object get(int index):获取指定index位置的元素

4.int indexOf(Object obj):返回obj在集合中首次出现的位置

5.int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置

6.Object remove(int index):移除指定index位置的元素,并返回此元素

7.Object set(int index, Object ele):设置指定index位置的元素为ele

8.List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex 位置的子集合

@Test
    public void test1(){
        ArrayList list=new ArrayList();
        list.add(123);
        list.add(456);
        list.add("aa");
        list.add(new Person("tom",12));
        list.add(456);//可重复
        System.out.println(list);
        //void add(int index ,object ele)在index的位置插入元素
        list.add(1,"bb");
        System.out.println(list);
        //addAll(int index ,collection ele)
        List list1 = Arrays.asList(1, 2, 3);
        list.addAll(0,list1);
        System.out.println(list);
        //get(int index )根据索引获取数据
        System.out.println(list.get(0));
        //indexof()首次出现的位置
        int index = list.indexOf(4567);//
        System.out.println(index);
        System.out.println(list.lastIndexOf(456));
        //remove(int index)按照索引删除
        Object obj = list.remove(0);//删除位置的元素
        System.out.println(obj);
        System.out.println(list);//删除往前移动
//        set(int index ,Object ele) 设置指定位子的元素ele
        list.set(0,"aa");
        System.out.println(list);
        //list sublist(int fromindex ,int toindext)左闭右和
        List subList = list.subList(0, 2);
        System.out.println(subList);//要确定的返回值
        System.out.println(list);//本身的list不变

    }


java 集合详细解析 List接口 Set接口 map接口_第2张图片

* 遍历:1,Itersator迭代器

* 2.增强for循环

3.用普通的循环

Test
    public void test5(){
        ArrayList list=new ArrayList();
        list.add(123);
        list.add(456);
        list.add("aa");
        list.add(new Person("tom",12));
        list.add(456);//可重复
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //方式二增强for循环
        for (Object obj:list){
            System.out.println(obj);
        }
        for (int i = 0; i 

List实现类之二:LinkedList

对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高

 LinkedList:双向链表,内部没有声明数组,而是定义了Node类型的first和last, 用于记录首末元素。同时,定义内部类Node,作为LinkedList中保存数据的基 本结构。Node除了保存数据,还定义了两个变量: prev变量记录前一个元素的位置  next变量记录下一个元素的位置

底层的双链表形式:

java 集合详细解析 List接口 Set接口 map接口_第3张图片

 底层双链表的是实现图:

java 集合详细解析 List接口 Set接口 map接口_第4张图片

新增方法:

1.void addFirst(Object obj) 在第一个位置添加

2. void addLast(Object obj) 最后一个位置添加

3. Object getFirst() 得到第一位置集合的对象

4.Object getLast() 得到最后一个位置集合的对象

5. Object removeFirst() 移除第一个位置集合的对象

6. Object removeLast()移除最后一个位置集合的对象

以上比较简单就不做代码演示了。

List 实现类之三:Vector

Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList 相同,区别之处在于Vector是线程安全的。

在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时, 使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。

新增方法:  void addElement(Object obj)

1 void insertElementAt(Object obj,int index)

2  void setElementAt(Object obj,int index)

3 void removeElement(Object obj)

4 void removeAllElements()

List总结一下:

ArrayList和LinkedList的异同 二者都线程不安全,相对线程安全的Vector,执行效率高。 此外,ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于 随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。对于新增 和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。

ArrayList和Vector的区别 Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized),属于 强同步类。因此开销就比ArrayList要大,访问要慢。正常情况下,大多数的Java程序员使用 ArrayList而不是Vector,因为同步完全可以由程序员自己来控制。Vector每次扩容请求其大 小的2倍空间,而ArrayList是1.5倍。Vector还有一个子类Stack。

Collection子接口之二:Set接口

Set 接口概述

*set接口 无序的,不可重复的 ;类似于高中我们所学的集合,无序的性,确定性,互异性

这个确定性向党羽判断是否有误。

对于过滤问题,过滤相同的数据,使用HashSet lIinkedset treeset解决此问题。

Set接口是Collection的子接口,set接口没有提供额外的方法

 Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。

 Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法。

总结:

* Hashset:set接口的主要实现类 线程不安全的
   * linkedhashset :是hashset的子类,在hashset的基础上加上链条,
* 使得遍历其内部数据时,按照添加的顺序去遍历
* treeset:存储结构是一个树的结构 红黑树的方式存储的
* 要求存入treeset的数据必须是一个类建立的
* 可以按照添加队形的指定属性,进行排序
* set没有添加新的方法用的都是collection中的方法

Set实现类之一:HashSet

HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。

HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取、查找、删除 性能。

HashSet 具有以下特点:

不能保证元素的排列顺序

HashSet 不是线程安全的

集合元素可以是 null

HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相 等,并且两个对象的 equals() 方法返回值也相等。

对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。

这文章里边有单独的说明hashset

点击此链接查看  HashSet的实现过程,以及hash表的说明

Set实现类之二:LinkedHashSet

LinkedHashSet 是 HashSet 的子类 linkedhashset :是hashset的子类,在hashset的基础上加上链条, 使得遍历其内部数据时,按照添加的顺序去遍历。

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

LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。 LinkedHashSet 不允许集合元素重复。

/**
 * LinkedHashSet的使用 作为hashset的子类 再添加数据的同时,每个数据还维护了两个变量
 * 记录数据和后一个数据,linkedhashset 的效率高于hashset频繁遍历操作
 */

上代码:

 @Test
    public void test2(){
        Set set=new LinkedHashSet();
        set.add(456);
        set.add(123);
        set.add("aa");
        set.add("cc");
        set.add("cc");//set接口中有int hashCode();重写
        set.add(new User("tom",12));
        set.add(new User("tom",12));
        set.add(123);
        //无序性不等于随机性 根据hash值来判断的相较于list有序是无序的
        //hashset的底层是数组存的通过hash值在数组中添加存储位置

        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }


    }

结果图:

java 集合详细解析 List接口 Set接口 map接口_第5张图片

HashSet底层结构:

java 集合详细解析 List接口 Set接口 map接口_第6张图片

Set实现类之三:TreeSet

TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。

TreeSet底层使用红黑树结构存储数据  新增的方法如下: (了解)

Comparator comparator()

Object first()

Object last()

Object lower(Object e)

Object higher(Object e)

SortedSet subSet(fromElement, toElement)

SortedSet headSet(toElement)

SortedSet tailSet(fromElement) TreeSet 两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。

理解:

1.向treeset中添加的数据 要求是相同类的对象 才可以比较大小,不能添加不同类的对象

* 自动从小到大排序 *

2两种排序方式

* 1.自然排序 比较两个对象是否相同的标准为compareto()返回0,不再是equals()实现compareto的接口

* treeset 不能放相同的数据

treeset和treemap 采用红黑树的形式

 定制排序 comprartor打交道

在定制排序中 比较两个对象是否相同的标准为:compare()返回0不再是equals();

TreeSet和TreeMap 采用红黑树的存储结构

特点:有序,查询速度比List快

红黑树:

java 集合详细解析 List接口 Set接口 map接口_第7张图片

 排 序—自然排序

自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元 素之间的大小关系,然后将集合元素按升序(默认情况)排列

如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。

实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。

Comparable 的典型实现: BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小 进行比较  Character:按字符的 unicode值来进行比较  Boolean:true 对应的包装类实例大于 false 对应的包装类实例  String:按字符串中字符的 unicode 值进行比较  Date、Time:后边的时间、日期比前面的时间、日期大。

向 TreeSet 中添加元素时,只有第一个元素无须比较compareTo()方法,后面添加的所有元素都会调用compareTo()方法进行比较。

因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同 一个类的对象。 对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通compareTo(Object obj) 方法比较返回值。 当需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保 证该方法与 compareTo(Object obj) 方法有一致的结果:如果两个对象通过 equals() 方法比较返回 true,则通过 compareTo(Object obj) 方法比较应返回 0。 否则,让人难以理解。

自然排序:

 @Test
    public void test1(){
        TreeSet set = new TreeSet();

        set.add(new User("tom",12));
        set.add(new User("jiso",50));
        set.add(new User("xiao",60));
        set.add(new User("da",40));
        set.add(new User("duo",11));
        set.add(new User("duo",15));
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

class User implements Comparable{
    private String name;
    private int age;
    public User(){}
    public User(String name,int age){
        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 "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (age != user.age) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    //    按照姓名从小到大 从大到小 填个-负号
    @Override
    public int compareTo(Object o) {
        if (o instanceof User) {
            User user = (User) o;
            //return -this.name.compareTo(user.name);
            int compare = -this.name.compareTo(user.name);
               if (compare !=0){
                   return compare;
            }else {
                   return Integer.compare(this.age, user.age);//从小到大
               }
        } else {
            throw new RuntimeException("输入类型不匹配");
        }

    }

结果按照姓名排序:

java 集合详细解析 List接口 Set接口 map接口_第8张图片

排序—定制排序:

TreeSet的自然排序要求元素所属的类实现Comparable接口,如果元素所属的类没 有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照 其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来 实现。需要重写compare(T o1,T o2)方法。

利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表 示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。

要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构 造器。

此时,仍然只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异 常。

使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0。

@Test
    public void test2(){
        Comparator com=new Comparator() {//实现这个接口 比較器
            //按照年龄从小到大排序 id一样的就不要了
            @Override
            public int compare(Object o1, Object o2) {
               if (o1 instanceof User && o2 instanceof User){
                   User u1= (User) o1;
                   User u2= (User) o2;
                   return Integer.compare(u1.getAge(),u2.getAge());
               }else {
                   throw  new RuntimeException("输入数据类型不匹配");
               }
            }
        };
        TreeSet set = new TreeSet(com);
        set.add(new User("tom",12));
        set.add(new User("jiso",50));
        set.add(new User("xiao",60));
        set.add(new User("da",11));
        set.add(new User("duo",11));
        set.add(new User("duo",15));
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}
class User implements Comparable{
    private String name;
    private int age;
    public User(){}
    public User(String name,int age){
        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 "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (age != user.age) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    //    按照姓名从小到大 从大到小 填个-负号
    @Override
    public int compareTo(Object o) {
        if (o instanceof User) {
            User user = (User) o;
            //return -this.name.compareTo(user.name);
            int compare = -this.name.compareTo(user.name);
               if (compare !=0){
                   return compare;
            }else {
                   return Integer.compare(this.age, user.age);//从小到大
               }
        } else {
            throw new RuntimeException("输入类型不匹配");
        }

    }

名字相同按照年龄定制排序:这个两个duo是相同的,然后再自然排序中并不是 这样的。这是相同对象并没有相同元素。

结果图如下:

java 集合详细解析 List接口 Set接口 map接口_第9张图片

 *一Map接口

* Map接口 存儲双列数据 键值对的形式 类似于高中的函数的形式y=f(x) 1.2

* HashMap:作为map的主要实现类 线程不安全 效率高 可以存储 null的key和value

* ---linkedHashMap 1.4 增删改查 速度快 保证在遍历map元素时可以按照添加的顺序进行遍历,

* 原因 在原有的hashmap底层的结构基础上 添加一个键值对,指向前一个或后一个 找前后更方便 * 使用:对于平凡的遍历操作,此类执行效率高于hashmap

* -----treeMap:1.2有序键值对 可以按照添加的key value 进行排序 进行排序遍历,按照key的值进行排序,底层是个树形结构

* 此时考虑可以的自然排序 或定制排序

 * 底层结构不同 使用的是红黑树 特殊的树型结构 treeset treemap用的是红黑树

* ----* Hashtable :作为一个古老的实现类:1.1 线程安全效率低 一般不适用 线程安全用connections

* --- --hashtable的子类Properties;常用来处理配置文件:key value都是string类型都是字符类型 *

java 集合详细解析 List接口 Set接口 map接口_第10张图片

 Map接口概述:

Map与Collection并列存在。用于保存具有映射关系的数据:key-value

Map 中的 key 和 value 都可以是任何引用类型的数据

Map 中的 key 用Set来存放,不允许重复,即同一个 Map对象所对应的类,须重写hashCode()和equals()方法。

常用String类作为Map的“键”。

key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到 唯一的、确定的 value

Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和 Properties。其中,HashMap是 Map 接口使用频率最高的实现类。

键值对 key->value 对应的方式

java 集合详细解析 List接口 Set接口 map接口_第11张图片

hashMap底层:
数组 加 链表 jdk7
数组 加 链表 加 红黑树  jdk8

二:Map机制的理解:

map的键值对 :value可以重复,key不能重复 相当于是用set存储的,value可以重复,无序的用collection集合存储单列数据存储

* put(key ,value);两个两个放,但是是一个一个放的 entry 中前边一个k后边一个v,entry的特点是无序的,不可重复的用set来装 * * 可以多对一 不能一对多

* map中的key是无序的不可重复的,使用set存储所有key --- 要求我们的key要重写equals()方法和hashcode方法

*针对hashmap来说的

* map中的value是无序的,但是是可重复 使用collection来存储value---values所在的类重写equals(),存的时候一般用
* 一个键值对key--value 构成了以entry对象

* map中的entry是无序的,不可重复的,使用set存储所有entry

三Hashmap的底层实现原理:

* 以jdk7为例说明 :
* HashMap map=new HashMap();
* 在实例化话后,底层创建了一个长度为16的以为数组 entry[] table   key entry value
*  可能已经执行过多次put
* map.put(key1,value1);
* 首先调用key1所在类的hashcode()计算key1哈希值,此哈希值经过某种算法计算以后,得到entry数组是一个数组中的存放位置
* 如果此位置上的数据为空 key1 value1直接添加成功 添加到entry中 情况1
* 如果此位置数据不为空,意味着此位置上存在一个或多个数据(以链表的形式存在),比较我们key1和已经存在的一个或多个哈希值
* 如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1--value1添加成功。情况2
* 如果key1的哈希值与某一个数据(key2-value2)已存在的哈希值相同,继续比较:调用key1所在类的equals()方法,比较
*       如果equals()返回false 意味着key1-value1添加成功 情况3
*       如果equals()返回true :使用value1替换value2.:eg put("tom",23) put("tom",45),修改的作用
*
*       情况2 情况3  有数据,链表的方式存储 拉链法 七上八下
*       添加过程中,会涉及扩容问题 默认扩容方式:扩容为原来的二倍,将原有的数据复制过来。
*       jdk8
*       new HashMap():底层没有出创建一个长度我16的数组
*       2.jdk8底层的数组是 node[] 而非entry[]
*       首次调用put()方法式,底层创建长度为16的长度
*       原理jdk7的底层结构只有 数组加链表,jdk8中底层结构:数组加链表加红黑树
*       当数组的某一个索引位置上的元素以链表形式存在的数据个数>8,且当前数组的长度>64时,此时索引位置上的所有数据改为红黑树存储
*       方便查找,二叉树相当于折半查找 二叉树排序树,红黑树,优化

看的明白java 集合详细解析 List接口 Set接口 map接口_第12张图片

 HashMap的内部存储结构其实是数组和链表的结合。当实例化一个HashMap时, 系统会创建一个长度为Capacity的Entry数组,这个长度在哈希表中被称为容量 (Capacity),在这个数组中可以存放元素的位置我们称之为“桶”(bucket),每个 bucket都有自己的索引,系统可以根据索引快速的查找bucket中的元素。

 每个bucket中存储一个元素,即一个Entry对象,但每一个Entry对象可以带一个引 用变量,用于指向下一个元素,因此,在一个桶中,就有可能生成一个Entry链。 而且新添加的元素作为链表的head。

 添加元素的过程: 向HashMap中添加entry1(key,value),需要首先计算entry1中key的哈希值(根据 key所在类的hashCode()计算得到),此哈希值经过处理以后,得到在底层Entry[]数 组中要存储的位置i。如果位置i上没有元素,则entry1直接添加成功。如果位置i上 已经存在entry2(或还有链表存在的entry3,entry4),则需要通过循环的方法,依次 比较entry1中key和其他的entry。如果彼此hash值不同,则直接添加成功。如果 hash值不同,继续比较二者是否equals。如果返回值为true,则使用entry1的value 去替换equals为true的entry的value。如果遍历一遍以后,发现所有的equals返回都 为false,则entry1仍可添加成功。entry1指向原有的entry元素。

Map接口:常用方法

添加、删除、修改操作: 
1 Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中 
2 void putAll(Map m):将m中的所有key-value对存放到当前map中 
3 Object remove(Object key):移除指定key的key-value对,并返回value 
4 void clear():清空当前map中的所有数据
元素查询的操作: 
1 Object get(Object key):获取指定key对应的value 
2 boolean containsKey(Object key):是否包含指定的key 
3 boolean containsValue(Object value):是否包含指定的value 
4 int size():返回map中key-value对的个数 
5 boolean isEmpty():判断当前map是否为空  boolean equals(Object obj):判断当前map和参数对象obj是否相等 
元视图操作的方法: 
1 Set keySet():返回所有key构成的Set集合 
2 Collection values():返回所有value构成的Collection集合 
3 Set entrySet():返回所有key-value对构成的Set集合

代码展示:

package Map;

import jihe.Person;
import org.junit.Test;

import java.util.*;


/**
 * Map接口 存儲双列数据 键值对的形式 类似于高中的函数的形式y=f(x) 1.2
 * HashMap:作为map的主要实现类 线程不安全 效率高 可以存储 null的key和value
 *  ---linkedHashMap 1.4 增删改查 速度快 保证在遍历map元素时可以按照添加的顺序进行遍历,
 *  原因 在原有的hashmap底层的结构基础上 添加一个键值对,指向前一个或后一个 找前后更方便
 *  使用:对于平凡的遍历操作,此类执行效率高于hashmap
 * -----treeMap:1.2有序键值对 可以按照添加的key value 进行排序 进行排序遍历,按照key的值进行排序,底层是个树形结构
 * 此时考虑可以的自然排序 或定制排序上
 * 底层结构不同 使用的是红黑树 特殊的树型结构 treeset treemap用的是红黑树
 * ----* Hashtable :作为一个古老的实现类:1.1 线程安全效率低 一般不适用 线程安全用connections
 *  ---    --hashtable的子类Properties;常用来处理配置文件:key value都是string类型都是字符类型
 *
 *
 *  hashMap底层:数组 加 链表jdk7
 *              数组 加 链表 加 红黑树 jdk8
 *  1.HashMap的底层原理:
 *  2.Hashtable 和hashtable的异同?
 *  3.CurrentHashMap 与hashtable的异同?有分段锁的形式线程安全如买票分时段买票
 *
 *
 * 二:Map机构的理解
 * map的键值对 :value可以重复,key不能重复 相当于是用set存储的,value可以重复,无序的用collection集合存储单列数据存储
 * put(key ,value);两个两个放,但是是一个一个放的 entry 中前边一个k后边一个v,entry的特点是无序的,不可重复的用set来装
 *
 * 可以多对一 不能一对多
 * map中的key是无序的不可重复的,使用set存储所有key --- 要求我们的key要重写equals()方法和hashcode方法
*针对hashmap来说的
 * map中的value是无序的,但是是可重复 使用collection来存储value---values所在的类重写equals(),存的时候一般用
 * 一个键值对key--value 构成了以entry对象
 * map中的entry是无序的,不可重复的,使用set存储所有entry
 *三 hashmap的底层实现原理?
 * 以jdk7为例说明 :
 * HashMap map=new HashMap();
 * 在实例化话后,底层创建了一个长度为16的以为数组 entry[] table   key entry value
 *  可能已经执行过多次put
 * map.put(key1,value1);
 * 首先调用key1所在类的hashcode()计算key1哈希值,此哈希值经过某种算法计算以后,得到entry数组是一个数组中的存放位置
 * 如果此位置上的数据为空 key1 value1直接添加成功 添加到entry中 情况1
 * 如果此位置数据不为空,意味着此位置上存在一个或多个数据(以链表的形式存在),比较我们key1和已经存在的一个或多个哈希值
 * 如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1--value1添加成功。情况2
 * 如果key1的韩系值与某一个数据(key2-value2)已存在的哈希值相同,继续比较:调用key1所在类的equals()方法,比较
 *       如果equals()返回false 意味着key1-value1添加成功 情况3
 *       如果equals()返回true :使用value1替换value2.eg put("tom",23) put("tom",45),修改的作用
 *
 *       情况2 情况3  有数据,链表的方式存储 拉链法 七上八下
 *       添加过程中,会涉及扩容问题 默认扩容方式:扩容为原来的二倍,将原有的数据复制过来。
 *       jdk8
 *       new HashMap():底层没有出创建一个长度我16的数组
 *       2.jdk8底层的数组是 node[] 而非entry[]
 *       首次调用put()方法式,底层创建长度为16的长度
 *       原理jdk7的底层结构只有 数组加链表,jdk8中底层结构:数组加链表加红黑树
 *       当数组的某一个索引位置上的元素以链表形式存在的数据个数>8,且当前数组的长度>64时,此时索引位置上的所有数据改为红黑树存储
 *       方便查找,二叉树相当于折半查找 二叉树排序树,红黑树,优化
 *
 *四:linekdehashmap底层实现原理
 * //频繁
 *五。第一层面:
 * Map接口中定义的方法
 *  添加、删除、修改操作:
 *  Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
 *  void putAll(Map m):将m中的所有key-value对存放到当前map中
 *  Object remove(Object key):移除指定key的key-value对,并返回value
 *  void clear():清空当前map中的所有数据
 *  元素查询的操作:
 *  Object get(Object key):获取指定key对应的value
 *  boolean containsKey(Object key):是否包含指定的key
 *  boolean containsValue(Object value):是否包含指定的value
 *  int size():返回map中key-value对的个数
 *  boolean isEmpty():判断当前map是否为空
 *  boolean equals(Object obj):判断当前map和参数对象obj是否相等
 *  元视图操作的方法:
 *  Set keySet():返回所有key构成的Set集合
 *  Collection values():返回所有value构成的Collection集合
 *  Set entrySet():返回所有key-value对构成的Set集合
 *
 *
 *
 * 常用方法:
 * 添加 put(Object key,Object value)
 * 删除 remove
 * 修改 put(Object key,Object value) 名称相同
 * 查询 get(Object key)
 * 长度 size()
 * 遍历 keyset() values() entrySet()
 *       */
public class MapTest {

    /*
  元视图操作的方法:
 Set keySet():返回所有key构成的Set集合
Collection values():返回所有value构成的Collection集合
 Set entrySet():返回所有key-value对构成的Set集合
     */
    //value可以重复,key不能重复 相当于是用set存储的 获取这个key
    // value可以重复,无序的用collection集合存储单列数据存储 获取这个value 得到
    //key=>value 构成 一个entry对象 set.entry()方法 或collection.entry()方法

    @Test
    public void test6(){
        //遍历哈希map
        Map map = new HashMap();
        map.put("aa",123);//key的值一般都是确定
        map.put("45",56);//key的值一般都是确定
        map.put(12,35);//key的值一般都是确定
        map.put("cc",123);//key的值一般都是确定
        //遍历一下key集合 :keySet()方法
        Set set = map.keySet();//一个set集合
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next()); //输出 aa cc 45 12按照hash值得顺序
        }
        System.out.println("============================");
        //遍历所有的value集合;键值对的value :用values()方法 //遍历 找这个value都是通过键值对的hash值 找到entry 来取的
        Collection values = map.values();//键值对的value的所有集合
        for (Object obj:values){
            System.out.println(obj);
        }
        System.out.println("============================");
        //遍历所有的key-value
        //Set entrySet():返回所有key-value对构成的Set集合
        Set entrySet = map.entrySet();
        Iterator iterator1 = entrySet.iterator();
        while (iterator1.hasNext()){
            Object obj = iterator1.next();
            Map.Entry entry= (Map.Entry) obj;
            System.out.println(entry.getKey()+"-->"+entry.getValue());//entry执行的key entry执行一个value

        }
        System.out.println("============================");
        //方式二 拼凑一个
        Set Keyset = map.keySet();//一个set集合
        Iterator iterator2 = Keyset.iterator();
        while (iterator2.hasNext()){
            Object key = iterator2.next();
            Object value=map.get(key);
            System.out.println(key+"-->"+value);//entry执行的key entry执行一个value
            //System.out.println(iterator.next()); //输出 aa cc 45 12按照hash值得顺序
        }

    }





/*     元素查询的操作:
 *  Object get(Object key):获取指定key对应的value
 *  boolean containsKey(Object key):是否包含指定的key
 *  boolean containsValue(Object value):是否包含指定的value
 *  int size():返回map中key-value对的个数
 *  boolean isEmpty():判断当前map是否为空
 *  boolean equals(Object obj):判断当前map和参数对象obj是否相等
    */
    @Test
    public void test5(){
        Map map = new HashMap();
        map.put("aa",123);//key的值一般都是确定
        map.put("45",56);//key的值一般都是确定
        map.put(12,35);//key的值一般都是确定
        map.put("cc",123);//key的值一般都是确定
        //Object get(Object key):获取指定key对应的value
        System.out.println(map.get("aa"));//不存在返回null
        //boolean containsKey(Object key):是否包含指定的key
        boolean isexist = map.containsKey("cc");//找到hash值
        System.out.println(isexist);
        //boolean containsValue(Object value):是否包含指定的value
        boolean b = map.containsValue(1234);
        System.out.println(b);//找到一个就是true
          //int size():返回map中key-value对的个数 获取对数
        map.clear();
        System.out.println(map.isEmpty());//boolean isEmpty():判断当前map是否为空
        //oolean equals(Object obj):判断当前map和参数对象obj是否相等
        Map map1 = new HashMap();
        map1.put("aa",123);//key的值一般都是确定
        map1.put("45",56);//key的值一般都是确定
        map1.put(12,35);//key的值一般都是确定
        map1.put("cc",123);//key的值一般都是确定
        Map map2 = new HashMap();
        map2.put("aa",123);//key的值一般都是确定
        map2.put("45",56);//key的值一般都是确定
        map2.put(12,35);//key的值一般都是确定
        map2.put("cc",123);//key的值一般都是确定
        boolean equals = map1.equals(map2);
        System.out.println(equals);

    }






    //        添加、删除、修改操作:
// *  Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
//      *  void putAll(Map m):将m中的所有key-value对存放到当前map中
//      *  Object remove(Object key):移除指定key的key-value对,并返回value
//      *  void clear():清空当前map中的所有数据
//    {aa=87, ff=123, zz=123, 45=56, 12=35} 等号区分左右 key与values
    @Test
    public void test3(){

        Map map = new HashMap();
        map.put("aa",123);//key的值一般都是确定
        map.put("45",56);//key的值一般都是确定
        map.put(12,35);//key的值一般都是确定
        map.put("cc",123);//key的值一般都是确定
        //修改的一个操作 替换原有的123
        map.put("aa",87);//key的值一般都是确定
        System.out.println(map);
        Map map1 = new HashMap();
        map1.put("ff",123);//key的值一般都是确定 value 可以相等的
        map1.put("zz",123);//key的值一般都是确定
        map.putAll(map1);
        System.out.println(map);
        //remove(Object key)
        Object value = map.remove("cc");//移除cc =>123
        Object value1 = map.remove("cccc");//没有返回null
        System.out.println(value);
        System.out.println(map);
        //clear()
        map.clear();//等同于把map中的数据清楚,不是变成了null 与map=null不同
        System.out.println(map.size());
        System.out.println(map);


    }

    @Test
    public void tes2(){
//        Map map = new LinkedHashMap();
        Map map = new HashMap();
        map=new LinkedHashMap();
        map.put("123","aa");
        map.put("456","cc");
        map.put("12","dd");
        map.put("13","ee");
        System.out.println(map);

    }
    @Test
    public void test1(){
        Person person = new Person();
        person.setName("小明");
        Map map = new HashMap();//可以放null健壮性好一点
        //map=new Hashtable();这样是不对的key value 健壮性差
        //map.put(null,null);
        map.put("22", new String[]{"sa", "as", "sf", "技术", "倒计时"});

        map.put(person.getName(),new Person("龙",12));
        System.out.println(map);
    }
}

结果1

 /*
  元视图操作的方法:
 Set keySet():返回所有key构成的Set集合
Collection values():返回所有value构成的Collection集合
 Set entrySet():返回所有key-value对构成的Set集合
     */
    //value可以重复,key不能重复 相当于是用set存储的 获取这个key
    // value可以重复,无序的用collection集合存储单列数据存储 获取这个value 得到
    //key=>value 构成 一个entry对象 set.entry()方法 或collection.entry()方法

java 集合详细解析 List接口 Set接口 map接口_第13张图片

 元素查询的操作:
 *  Object get(Object key):获取指定key对应的value
 *  boolean containsKey(Object key):是否包含指定的key
 *  boolean containsValue(Object value):是否包含指定的value
 *  int size():返回map中key-value对的个数
 *  boolean isEmpty():判断当前map是否为空
 *  boolean equals(Object obj):判断当前map和参数对象obj是否相等
    */

java 集合详细解析 List接口 Set接口 map接口_第14张图片

//        添加、删除、修改操作:
// *  Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
//      *  void putAll(Map m):将m中的所有key-value对存放到当前map中
//      *  Object remove(Object key):移除指定key的key-value对,并返回value
//      *  void clear():清空当前map中的所有数据
//    {aa=87, ff=123, zz=123, 45=56, 12=35} 等号区分左右 key与values

java 集合详细解析 List接口 Set接口 map接口_第15张图片

Map实现类之二:LinkedHashMap

LinkedHashMap 是 HashMap 的子类

在HashMap存储结构的基础上,使用了一对双向链表来记录添加元素的顺序

与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致。

java 集合详细解析 List接口 Set接口 map接口_第16张图片

Map实现类之三:TreeMap

 TreeMap存储 Key-Value 对时,需要根据 key-value 对进行排序。 TreeMap 可以保证所有的 Key-Value 对处于有序状态。

TreeSet底层使用红黑树结构存储数据

TreeMap 的 Key 的排序: 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有 的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException

定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口

TreeMap判断两个key相等的标准:两个key通过compareTo()方法或 者compare()方法返回0。

User类实现重写equals()方法 重写 hashcode()方法 实现implements Comparable

package Map;

class User implements Comparable{
    private String name;
    private int age;
    public User(){}
    public User(String name, int age){
        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 "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (age != user.age) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    //    按照姓名从小到大 从大到小 填个-负号
    @Override
    public int compareTo(Object o) {
        if (o instanceof User) {
            User user = (User) o;
            //return -this.name.compareTo(user.name);
            int compare = -this.name.compareTo(user.name);
               if (compare !=0){
                   return compare;
            }else {
                   return Integer.compare(this.age, user.age);//从小到大
               }
        } else {
            throw new RuntimeException("输入类型不匹配");
        }

    }
}
//向Treemap中添加key-value,要求必须由同一个类创建的对象
//因为要按照key进行排序,自然排序和定制排序
package Map;

import org.junit.Test;

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

public class TreeMapTest {
    //向Treemap中添加key-value,要求必须由同一个类创建的对象
    //因为要按照key进行排序,自然排序和定制排序
    @Test
    public void test(){
        TreeMap map = new TreeMap();
        User u1=new User("tom",23);
        User u2=new User("ross",30);
        User u3=new User("pigui",58);
        User u4=new User("zhu",25);
        map.put(u1,88);
        map.put(u2,100);
        map.put(u3,66);
        map.put(u4,77);
        Set set = map.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
    @Test
    public void test2(){
        TreeMap map = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof User && o2 instanceof User){
                    User u1= (User) o1;
                    User u2= (User) o2;
                    return Integer.compare(u1.getAge(),u2.getAge());

                }
                throw new RuntimeException("输入类型不匹配");
            }
        });
        User u1=new User("tom",23);
        User u2=new User("ross",30);
        User u3=new User("pigui",58);
        User u4=new User("zhu",25);
        map.put(u1,88);
        map.put(u2,100);
        map.put(u3,66);
        map.put(u4,77);
        Set set = map.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}

结果截图:

自然排序:

在User类中实现implements Comparable 重写compareTo()方法,以姓名的降序排序。

java 集合详细解析 List接口 Set接口 map接口_第17张图片

定制排序:

按照年龄的升序排序:利用interface Comparator 接口比较器,实现定制,姓名相同的情况下以age实现排序,这样避免,键值对相同元素加入不进去。。

java 集合详细解析 List接口 Set接口 map接口_第18张图片

Properties 类

Properties 类是 Hashtable 的子类,该对象用于处理属性文件

由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key 和 value 都是字符串类型

存取数据时,建议使用setProperty(String key,String value)方法和 getProperty(String key)方法

创建一个properties的文件

java 集合详细解析 List接口 Set接口 map接口_第19张图片

在jdbc中键入字符:等于 还有name都要挨着写,不能出现空格,换行必须定格写。不然使用容易出错

 java 集合详细解析 List接口 Set接口 map接口_第20张图片

测试代码如下:

package Map;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesTest {
    /*
     --hashtable的子类Properties;
     常用来处理配置文件:key value都是string类型都是字符类型
     */
    public static void main(String[] args)  {
        Properties pro = null;//物理上存在的文件 配置文件
        try {
            pro = new Properties();
            FileInputStream fis = new FileInputStream("D:\\javaweb\\JSP\\nb\\jdbc.properties");
            pro.load(fis);//加载流配置文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        String name = pro.getProperty("name");
        String password = pro.getProperty("password");
        System.out.println("name="+name+",password"+password);


    }
}

结果:与配置文件一致!

 java 集合详细解析 List接口 Set接口 map接口_第21张图片

Collections工具类:

一般我们使用的ArrayList,Hashset HashMap 它们的效率高,但是线程是不安全的,相比线程安全的相对的效率比较低。那么我们使用Collection工具类就可以解决,并且非常简单。

操作数组的工具类:Arrays

Collections 是一个操作 Set、List 和 Map 等集合的工具类

Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作, 还提供了对集合对象设置不可变、对集合对象实现同步控制等方法

排序操作:(均为static方法)

reverse(List):反转 List 中元素的顺序

shuffle(List):对 List 集合元素进行随机排序

sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序

sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序 swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换

Collections常用方法

查找、替换

Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素

Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回 给定集合中的最大元素

Object min(Collection) 根据元素的自然顺序,返回给定集合中的最小元素

Object min(Collection,Comparator)  根据 Comparator 指定的顺序,返回 给定集合中的最小元素

int frequency(Collection,Object):返回指定集合中指定元素的出现次数

void copy(List dest,List src):将src中的内容复制到dest中

boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧

 上代码:

package Collecttions;

import org.junit.Test;

import java.util.*;

/**
 * collections:操作的collection,map的工具类
 *
 *
 * Collections和collection的区别?
 * collection 是集合的总体集合接口,是所有集合的总接口
 * Collections工具类
 *排序操作:(均为static方法)
 * reverse(List):反转 List 中元素的顺序
 * shuffle(List):对 List 集合元素进行随机排序
 * sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
 * sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
 * swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
 *
 *查找、替换
 * Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
 * Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回
 * 给定集合中的最大元素
 * Object min(Collection)
 * Object min(Collection,Comparator)
 * int frequency(Collection,Object):返回指定集合中指定元素的出现次数
 * void copy(List dest,List src):将src中的内容复制到dest中
 * boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换
 * List 对象的所有旧值
 */

public class CollectionsTest {
    @Test
    public void test(){
        //reverse(List):反转 List 中元素的顺序
       List list = new ArrayList();
        list.add(123);
        list.add(123);
        list.add(123);
        list.add(456);
        list.add(234);
        list.add(78);
        list.add(456);
        list.add(98);
        System.out.println(list);
        Collections.reverse(list);
        Collections.shuffle(list);
        Collections.sort(list);//升序
        Collections.swap(list,1,2);
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return -Integer.compare((Integer) o1, (Integer) o2);
            }

        });
        System.out.println(list);
        int frequency = Collections.frequency(list, 123);
        System.out.println(list);
        System.out.println(frequency);
        //void copy(List dest,List src):将src中的内容复制到dest中
        //报异常Source does not fit in dest
//        List list1 = new ArrayList(list.size());
//        Collections.copy(list1,list);
        List list1 = Arrays.asList(new Object[list.size()]);
        Collections.copy(list1,list);
        System.out.println(list);
        System.out.println(list1);
        //线程是安全的 map set 都可以实现线程安全的
        List synchronizedList = Collections.synchronizedList(list);



    }
}

结果:

java 集合详细解析 List接口 Set接口 map接口_第22张图片Collections常用方法:同步控制

//线程是安全的 map set 都可以实现线程安全的
List synchronizedList = Collections.synchronizedList(list);

 Map Set 实现方式java 集合详细解析 List接口 Set接口 map接口_第23张图片

 看一下代码内部结构:

都是使用SynchronizedCollection 同步线程安全的形式存在,这样更加简单的解决了ArrayList,Hashset HashMap 它们的效率高,但是线程是不安全的这个问题。

java 集合详细解析 List接口 Set接口 map接口_第24张图片

你可能感兴趣的:(java,c语言,c#,eclipse,intellij,idea)