栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

集合Collection&Map

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

集合Collection&Map

目录

一,集合容器概述

1.什么是集合?

2.集合的特点

3.集合和数组的区别

4常用集合类

 二,Collection接口,子接口,常用实现类

1.Collection集合

遍历步骤

2.List接口(数据可重复)

1.ArrayList

2.linkedList(底层是链表结构实现,查询慢、增删快)

3.Set

1.HashSet

3.linkedHashSet(数据有序,不重复)

2.TreeSet

三,Map接口,常用实现类

基本功能(方法)

1.HashMap

2.HashTable

3.TreeMap

底层: 红黑树(自平衡的排序二叉树)


一,集合容器概述

1.什么是集合?

集合框架:用于存储数据的容器。

集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。
任何集合框架都包含三大块内容:(1)对外的接口、(2)接口的实现(3)对集合运算的算法。

接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象

实现:是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构(重用性),例如:ArrayList、linkedList、HashSet、HashMap。

算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。算法是可复用的函数,减少了程序设计的辛劳。

集合框架通过提供数据结构和算法(底成设计),免除了为改编对象或转换代码以便联合这些API而去写大量的代码。 它提高了程序速度和质量。

2.集合的特点

1.对象用于封装数据,集合用于存储对象

2.集合是可变长度

3.集合和数组的区别

1.数组是固定长度;集合是可变长度

2.数组存储基本数据类型和引用数据类型;而集合只能存储引用数据类型

3.数组存储的元素必须是同一数据类型;集合存储的对象可以是不同数据类型

4常用集合类

Collection接口和Map接口是所有集合框架的父接口

1.Collection接口的子接口包括:Set接口和List接口

2.Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等

3.Set接口的实现类主要有:HashSet、TreeSet、linkedHashSet等

4.List接口的实现类主要有:ArrayList、linkedList、Stack以及Vector等

 二,Collection接口,子接口,常用实现类

1.Collection集合

(1)概述

  • Collection集合概述

    • 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素

    • JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现

(2)基本使用

public class CollectionDemo01 {
    public static void main(String[] args) {
        //创建Collection集合的对象
        Collection c = new ArrayList();

        //添加元素:boolean add(E e)
        c.add("hello");
        c.add("world");
        c.add("java");

        //输出集合对象
        System.out.println(c);
    }
}

(3)常用方法

方法名说明
boolean add(E e)添加元素
boolean remove(Object o)从集合中移除指定的元素
void clear()清空集合中的元素
boolean contains(Object o)判断集合中是否存在指定的元素
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中元素的个数

(4)遍历

  • 迭代器的介绍

    • 迭代器,集合的专用遍历方式

    • Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到

    • 迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的

  • 常用方法
  •    boolean hasNext​()   如果迭代具有更多元素,则返回 true 。  
  •    E next​()            返回迭代中的下一个元素。  
       default void remove​() 从底层集合中删除此迭代器返回的最后一个元素(可选操作)。  
public class IteratorDemo {
    public static void main(String[] args) {
        //创建集合对象
        Collection c = new ArrayList<>();
        //添加元素
        c.add("hello");
        c.add("world");
        c.add("java");
        c.add("javaee");
        //Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
        Iterator it = c.iterator();
        //用while循环改进元素的判断和获取
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
    }
}

遍历步骤

2.List接口(数据可重复)

(1)概述

  • 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素

  • 与Set集合不同,列表通常允许重复的元素

(2)特点

  • 有索引

  • 可以存储重复元素

  • 元素存取有序

(3)特有方法

方法名描述
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

(4)List遍历

1)通过for循环遍历集合(因为迭代器遍历的过程中,通过集合对象修改了集合中的元素,造成了迭代器获取元素中判断预期修改值和实际修改值不一致,则会出现:ConcurrentModificationException )

2)ListIterator(列表迭代器)(通过迭代器创建其对象,用iterctor()创建
因为List集合继承Collection集合)

3)增强for循环

代码演示:

//学生类
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(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;
    }
}
//测试类
public class ListDemo {
    public static void main(String[] args) {
        //创建List集合对象
        List list = new ArrayList();

        //创建学生对象
        Student s1 = new Student("林青霞", 30);
        Student s2 = new Student("张曼玉", 35);
        Student s3 = new Student("王祖贤", 33);

        //把学生添加到集合
        list.add(s1);
        list.add(s2);
        list.add(s3);

        //迭代器:集合特有的遍历方式
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Student s = it.next();
            System.out.println(s.getName()+","+s.getAge());
        }
        System.out.println("--------");

        //普通for:带有索引的遍历方式
        for(int i=0; i 

1.ArrayList

(1)概述

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

ArrayList 继承了 AbstractList ,并实现了 List 接口。

ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.ArrayList; // 引入 ArrayList 类

ArrayList objectName =new ArrayList<>();  // 初始化
  • E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
  • objectName: 对象名。

ArrayList 是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。

(2)特点

AraryList(底层是数组结构实现,查询快,增删慢)

        有序:存储和取出的元素顺序,

                 所以查询快,用户可以精确控制列表中每一个元素的插入位置。用户可以通过整数索引                   访问元素,并搜索列表中的元素。
        可重复:存储的元素可以重复

2.linkedList(底层是链表结构实现,查询慢、增删快)

链表(linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。

链表可分为单向链表和双向链表。

一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。

一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。

Java linkedList(链表) 类似于 ArrayList,是一种常用的数据容器。

与 ArrayList 相比,linkedList 的增加和删除的操作效率更高,而查找和修改的操作效率较低。

以下情况使用 ArrayList :

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。

以下情况使用 linkedList :

  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

linkedList 继承了 AbstractSequentialList 类。

linkedList 实现了 Queue 接口,可作为队列使用。

linkedList 实现了 List 接口,可进行列表的相关操作。

linkedList 实现了 Deque 接口,可作为队列使用。

linkedList 实现了 Cloneable 接口,可实现克隆。

linkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

 特有方法

方法名说明
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素

3.Set

(1)概述和特点

1.不包含重复元素得集合
2.没有带索引的方法,所以不能使用普通for循环遍历
(但可以通过迭代器或这增强for循环遍历)
3.HashSet:对集合的迭代顺序不作任何保证

(2)基本使用

public class SetDemo {
    public static void main(String[] args) {
        //创建集合对象
        Set set = new HashSet();

        //添加元素
        set.add("hello");
        set.add("world");
        set.add("java");
        //不包含重复元素的集合
        set.add("world");

        //遍历
        for(String s : set) {
            System.out.println(s);
        }
    }
}

1.HashSet

概述和特点

HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。

HashSet 允许有 null 值。

HashSet 是无序的,即不会记录插入的顺序。

HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。

HashSet 实现了 Set 接口。

HashSet 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.HashSet; // 引入 HashSet 类

以下实例我们创建一个 HashSet 对象 sites,用于保存字符串元素:

HashSet sites = new HashSet();

代码展示

//添加元素 添加元素可以使用 add() 方法
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet sites = new HashSet();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");  // 重复的元素不会被添加
        System.out.println(sites);
    }
}

//判断元素是否存在: contains() 方法
public class RunoobTest {
    public static void main(String[] args) {
    HashSet sites = new HashSet();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");  // 重复的元素不会被添加
        System.out.println(sites.contains("Taobao"));
    }
}

//删除元素 remove() 

public class RunoobTest {
    public static void main(String[] args) {
    HashSet sites = new HashSet();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");     // 重复的元素不会被添加
        sites.remove("Taobao");  // 删除元素,删除成功返回 true,否则为 false
        System.out.println(sites);
    }
}

//删除集合中所有元素可以使用 clear 方法:
public class RunoobTest {
    public static void main(String[] args) {
    HashSet sites = new HashSet();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");     // 重复的元素不会被添加
        sites.clear();  
        System.out.println(sites);
    }
}

//迭代 HashSet
public class RunoobTest {
    public static void main(String[] args) {
    HashSet sites = new HashSet();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");     // 重复的元素不会被添加
        for (String i : sites) {
            System.out.println(i);
        }
    }
}

HashSet集合保证元素唯一性源码

原理:

1.根据对象的哈希值计算存储位置

如果当前位置没有元素则直接存入

如果当前位置有元素存在,则进入第二步

2.当前元素的元素和已经存在的元素比较哈希值

如果哈希值不同,则将当前元素进行存储

如果哈希值相同,则进入第三步

3.通过equals()方法比较两个元素的内容

如果内容不相同,则将当前元素进行存储

如果内容相同,则不存储当前元素

2.图解

3.linkedHashSet(数据有序,不重复)

概述:

 linkedHashSet 继承与 HashSet,并且其内部是通过 linkedHashMap 来实现的。有点类似于我们之前说的linkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。

特点:-哈希表和链表实现的Set接口,具有可预测的迭代次序
          - 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
          - 由哈希表保证元素唯一,也就是说没有重复的元素

基本使用

public class linkedHashSetDemo {
    public static void main(String[] args) {
        //创建集合对象
        linkedHashSet linkedHashSet = new linkedHashSet();

        //添加元素
        linkedHashSet.add("hello");
        linkedHashSet.add("world");
        linkedHashSet.add("java");

        linkedHashSet.add("world");

        //遍历集合
        for(String s : linkedHashSet) {
            System.out.println(s);
        }
    }
}

2.TreeSet

TreeSet<>是继承于AbstractSet()并实现了几个接口

特点:

- 元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
  - TreeSet():根据其元素的自然排序进行排序
  - TreeSet(Comparator comparator) :根据"指定"的比较器进行排序
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以不包含重复元素的集合.

有两种排序:自然排序Comparable,比较排序Comparator、

Comparable(就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法 )

@Override
    public int compareTo(Student s) {
//        return 0;//不添加
//        return 1;//降序——>升序
//        return -1;//升序—-->升序
        //按照年龄从小到大排序
       int num = this.age - s.age;
//        int num = s.age - this.age;
        //年龄相同时,按照姓名的字母顺序排序
       int num2 = num==0?this.name.compareTo(s.name):num;
        return num2;
    }

Comparator(让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法 )

  • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

 //创建集合对象
        TreeSet ts = new TreeSet(new Comparator() {
            @Override
            public int compare(Student s1, Student s2) {
                //this.age - s.age
                //s1,s2
                int num = s1.getAge() - s2.getAge();
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                return num2;
            }
        });

三,Map接口,常用实现类

Map集合概述:

interface Map  K:键的类型;V:值的类型

  • Map集合的特点

    • 键值对映射关系

    • 一个键对应一个值

    • 键不能重复,值可以重复

    • 元素存取无序

Map集合的基本使用

public class MapDemo01 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();

        //V put(K key, V value) 将指定的值与该映射中的指定键相关联
        map.put("itheima001","林青霞");
        map.put("itheima002","张曼玉");
        map.put("itheima003","王祖贤");
        map.put("itheima003","柳岩");

        //输出集合对象
        System.out.println(map);
    }
}

基本功能(方法)
方法名说明
V put(K key,V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean containsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中键值对的个数

public class MapDemo02 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();

        //V put(K key,V value):添加元素
        map.put("张无忌","赵敏");
        map.put("郭靖","黄蓉");
        map.put("杨过","小龙女");

        //V remove(Object key):根据键删除键值对元素
//        System.out.println(map.remove("郭靖"));
//        System.out.println(map.remove("郭襄"));

        //void clear():移除所有的键值对元素
//        map.clear();

        //boolean containsKey(Object key):判断集合是否包含指定的键
//        System.out.println(map.containsKey("郭靖"));
//        System.out.println(map.containsKey("郭襄"));

        //boolean isEmpty():判断集合是否为空
//        System.out.println(map.isEmpty());

        //int size():集合的长度,也就是集合中键值对的个数
        System.out.println(map.size());


        //输出集合对象
        System.out.println(map);
    }
}

获取功能

方法名说明
V get(Object key)根据键获取值
Set keySet()获取所有键的集合
Collection values()获取所有值的集合
Set> entrySet()获取所有键值对对象的集合
public class MapDemo03 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();

        //添加元素
        map.put("张无忌", "赵敏");
        map.put("郭靖", "黄蓉");
        map.put("杨过", "小龙女");

        //V get(Object key):根据键获取值
//        System.out.println(map.get("张无忌"));
//        System.out.println(map.get("张三丰"));

        //Set keySet():获取所有键的集合
//        Set keySet = map.keySet();
//        for(String key : keySet) {
//            System.out.println(key);
//        }

        //Collection values():获取所有值的集合
        Collection values = map.values();
        for(String value : values) {
            System.out.println(value);
        }
    }
}

遍历:


public class MapDemo01 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();

        //添加元素
        map.put("张无忌", "赵敏");
        map.put("郭靖", "黄蓉");
        map.put("杨过", "小龙女");

        //获取所有键的集合。用keySet()方法实现
        Set keySet = map.keySet();
        //遍历键的集合,获取到每一个键。用增强for实现
        for (String key : keySet) {
            //根据键去找值。用get(Object key)方法实现
            String value = map.get(key);
            System.out.println(key + "," + value);
        }
    }
}


public class MapDemo02 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();

        //添加元素
        map.put("张无忌", "赵敏");
        map.put("郭靖", "黄蓉");
        map.put("杨过", "小龙女");

        //获取所有键值对对象的集合
        Set> entrySet = map.entrySet();
        //遍历键值对对象的集合,得到每一个键值对对象
        for (Map.Entry me : entrySet) {
            //根据键值对对象获取键和值
            String key = me.getKey();
            String value = me.getValue();
            System.out.println(key + "," + value);
        }
    }
}

1.HashMap

底层:

JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间

概述:

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。

HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。

HashMap 是无序的,即不会记录插入的顺序。

HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

HashMap 的 key 与 value 类型可以相同也可以不同,可以是字符串(String)类型的 key 和 value,也可以是整型(Integer)的 key 和字符串(String)类型的 value。

2.HashTable

底层:

数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的

3.TreeMap

底层: 红黑树(自平衡的排序二叉树)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605689.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号