Java集合

一,集合概述:

1.什么是集合类,为什么需要用到集合类

当我们需要保存一组一样(类型相同)的元素的时候,我们应该使用一个容器

来存储,数组就是这样一个容器。

数组的缺点:

数组一旦定义,长度将不能在变化

然而在实际开发中,存储的数据长度是不定的,是会变化的,在存储数据时,不同的使用场景,可以使用不同的数据结构,于是我们需要一些能够动态增长长度的容器来保存我们的数据,Java中对于各种数据结构的实现,就是我们用到的集合。

2.集合概述

Java的集合框架就是由许多接口,抽象类具体类组成的,都位于java。util包中

二,集合类体系结构

1.单列集合   :只能存在单个值

Collection接口定义了存取一组对象的方法,其子接口Set和List分别定义了不同的存储方法

    List接口:可以存储重复元素

    Set接口:不能存储重复元素

(1)List接口

List接口继承了Collection接口,有三个实现类

    ArrayList:底层是数组实现,查询快,中间删除慢

    LinkedList:底层是链表实现,查询慢,中间删除快

    Vector:底层是数组实现,相较于ArrayList添加了同步锁,多线程场景下使用安全

(一)ArrayList

ArrayList是长度可变的数组,在内存中分配连续的空间。

遍历元素和随机访问元素的效率比较高

ArrayList数组集合,默认可以存储object类型

实际开发中,一般建议一个集合对象最好只存储一种单一类型

使用泛型语法,为集合指定一个类型

ArrayList中的常用方法:

ArrayList<String> arrayList = new ArrayList();
arrayList.add("a");//末尾添加元素
arrayList.add(3,"u");//向指定位置添加元素                          arrayList.addAll(arrayList0);//把另一个集合数据添加进来
System.out.println(arrayList.remove(0));//根据索引删除对应的元素,并返回删除的元素System.out.println(arrayList.remove("b"));//根据内容删除第一次匹配的元素,
                                            删除成功返回true,否则返回false
System.out.println(arrayList.isEmpty());//判断集合是否为空,是的话返回true System.out.println(arrayList.contains("c"));//判断是否包含指定
arrayList.set(1,"E");//替换指定位置的
System.out.println(arrayList.get(4));//获取指定位置的元素System.out.println(arrayList.indexOf("a"));//获取指定元素首次出现的位置System.out.println(arrayList.size());//返回集合中实际添加元素的个数
arrayList.clear();//清空元素
ArrayList<String> arrayList = new ArrayList<>();创建一个默认是10的数组
ArrayList<String> arrayList = new ArrayList<>(50);创建一个指定容量的数组         ArrayList<String> arrayList2 = new ArrayList<>(arrayList);
                 创建一个集合时,把另一个集合数据添加打此集合中
String[]strings = arrayList.toArray(new String[arrayList.size()]);//把集合对象转为数组对象
 (二)LinkedList

LinkedList采用链表存储方式。插入、删除元素时效率比较高

LinkedList可以通过使用方法成为栈或队列

栈和队列
栈 :从头节点添加,从头节点删除
队列:排队   从尾添加  从头删除

LinledLis的常用方法:

        LinkedList<Integer> linkedList = new LinkedList<>();
                            linkedList.add(1);
                            linkedList.add(2);
                            linkedList.add(3);
                            linkedList.add(4);
                            linkedList.add(4);//从尾节点添加元素

        System.out.println(linkedList.get(3));//只能从头或者尾节点开始找,直到找到对应位置的元素
        System.out.println(linkedList);
                            linkedList.set(2,40);//指定位置元素替换成指定元素;
        System.out.println(linkedList.getFirst());//取头节点
        System.out.println(linkedList.getLast());//取尾节点
        System.out.println(linkedList.remove(2));//删除指定位置的元素
        System.out.println(linkedList.removeFirst());//删除头节点
        System.out.println(linkedList.removeLast());//删除尾节点
(三)List接口集合迭代

三种方式:

1.for循环

2.增强for循环的遍历

            方式一:for循环
                 支持遍历时,删除数据
                 注意删除后,后面元素前移

        for (int i = 0; i < arrayList.size(); i++) {
            if (arrayList.get(i).equals("a")  ){
                arrayList.remove(i);
                i--;
            }
        }
            方式二:增强for循环
                遍历时,不允许删除数据元素,如果删除元素会报错
        for (String s : arrayList){
            if (s.equals("a")){
                arrayList.remove(s);
            }
        }

3.迭代器遍历(Iterator)

            方式三  迭代器
        Iterator<String> iterator = arrayList.listIterator();
        while (iterator.hasNext()){
            String item = iterator.next();
            if (item.equals("a")){
                iterator.remove();//调用迭代器中的remove方法
            }
        }

(2)Set接口

Set接口继承了Collection接口

    Set中存储的元素是不重复的,Set中的元素是没有索引的

Set接口有两个实现类,且实现类的常用方法和迭代器与List接口的实现类的常用方法和迭代器一致

HashSet:HashSet类底层基于哈希表实现,元素位置是散列无序的

TreeSet:TreeSet类底层基于树形结构实现,元素进行指定的方式排列,存储的类型必须实现Comparable接口

(一)HashSet

HashSet 哈希(散列)本质上就是一个数组  算出余数是多少存在哈希表对应的位置,存储的元素是无序的

 HashSet是如何实现值不重复原理
底层用到两个方法  HashCode()   equal()
    先调用hashCode(),根据内容算出一个哈希值(int类型),先用整数哈希值比较,哈希值相同,说明内容也就相同了
        用哈希值判断是会存在风险的:内容不同,算出来的哈希值相同
    所以哈希值相同的情况下,再调用equal()判断内容

结论:向HashSet中添加的数据类型中,必须调用hashCode()和equal()方法

向HashSet中存储我们自己定义的Student类型,如果没有重写hashCode(),默认会调用Object类中的hashCode()
Object类中    public native int hashCode();是一个native修饰的方法(是本地方法,是由操作系统提供的),读取的是对象的内存地址
所以只要是new出来的对象,对象地址都不同
现在的需要是,对象中的内容相同,就判定为重复内容
需要对Object类中的equal()和hashCode()进行重写,根据内容计算哈希值,判断内容是否相等

(二)TreeSet

TreeSet 树 存储元素是有序(排序的)

TreeSet是树形结构,第一个存入的数据是根,再继续添加元素是,进行比较,大的往右子节点存储,小的往左子节点存储

TreeSet   底层使用的是红黑树   可以自平衡   避免成为链表

向TreeSet集合中添加的类型必须实现Compare接口

2.双列集合:可以存储两个值

(1)Map接口:

概述:实现了Map接口的集合类就是双列集合

          是一组键值对映射的

          键不能重复,每个键只能映射到一个值

          值可以重复

实现类
    HashMap
    TreeMap

(一)Map接口的常用方法
        HashMap<String,String> map = new HashMap<>();
                               map.put("x","xx");
                               map.put("a","44");
                               map.put("u","uu");
                               map.put("k","kk");
                               map.put("a","aa");//添加元素,逗号前为键,逗号后为值,出现重复键时,用后出现的键映射的值覆盖先出现的键值
       map.clear();//清空
        map.remove("a");//通过key删除对应的映射
        System.out.println(map.containsKey("a"));//判断是否包含指定的key
        System.out.println(map.containsValue("xx"));//判断是否包含指定的value
        System.out.println(map.isEmpty());//判断是否为空
        System.out.println(map.size());//存了几个key字节
        System.out.println(map.get("u"));//根据key获得对应的value

        Collection<String> values =  map.values();
        System.out.println(values);
        Set<String> s = map.keySet();

        System.out.println(map);//输出是无序的

(二)HashMap

可以存储一个为null的键,key和value都可以为null

底层用到的数据结构: 哈希表(数组),链表,红黑树

(三)TreeMap

TreeMap 底层实现是红黑树,可以根据键进行排序
  key值的类型必须实现 Comparable接口,重写Comparable方法

(四)HashTable

是无序的
也是哈希结构,方法都加了锁,在多线程场景下是安全的
不能存储为null的键和值

(五)Map集合的遍历

方式1:根据键找值

获取所有键的集合

遍历键的集合,获取到每一个键

根据键找值

方式2:根据键值对对象获取键和值

获取所有键值对对象的集合

遍历键值对对象的集合,获取到每一个键值对对象

根据键值对对象找键和值

        /*
           方式一:先拿到所有的key,循环key,每次拿到一个key,然后在上map中去找值,(不推荐)
         */
        Set<String> keyset = map.keySet();
        for (String key:keyset){
            System.out.println(key + ":" + map.get(key));
        }

        /*
            方式二:
            为了遍历方便,把所有的键值对,重新进行了一个提取,存入到一个entry类型集合中
         */
        Set<Map.Entry<String,String>> entries = map.entrySet();
        for (Map.Entry<String,String> entry:entries){
            System.out.println(entry.getKey() + ":" + entry.getValue());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值