Java-09-集合

Java-09-集合

集合类概述

数组长度是固定,如果要改变数组的长度需要创建新的数组将旧数组里面的元素拷贝过去,使用起来不方便。
java给开发者提供了一些集合类,能够存储任意长度的对象,长度可以随着元素的增加而增加,随着元素的减少而减少,使用起来方便一些。

集合类的特点

集合特定
List有序,可重复
Set无序,不可重复
Queue队列(先进先出),可重复

集合vs数组

数组集合
存储类型基本数据类型(值),引用数据类型(地址值)仅 引用数据类型(对象),若存基本数据类型->自动装箱,包装类
长度固定可变,随元素的增加而自动增长

集合框架

image-20210311103001486

image-20210311103724552

Java集合类主要由两个根接口Collection和Map派生而来,Collection又派生出List,Set,Queue三个子接口,而Map集合存储的东西比较特殊,它提供的是key到value的映射,存储的是键值对的集合,所以Java集合可大致分为List,Set,Queue,Map四种接口体系,上图中蓝色背景覆盖的是集合体系中常用的实现类

以ArrayList,该实现类为例

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

public class TestSet {


    public static void main(String[] args) {

        // 要想使用集合,需要创建对象,集合框架中有大量的接口和抽象类
        // 一些实现类能实例化集合对象
        Collection c = new ArrayList();

        //将字符串存入ArrayList集合中
        c.add("h");
        c.add("i");

        //size获得集合大小
        System.out.println(c.size());//2
        //ArrayList重写了toString 方法,输出了内容,而不是地址
        System.out.println(c);//[h, i]

        //如何遍历集合?使用迭代器 iterator
        //转数组遍历是不可取的,java提供了一个iterator的接口,在集合的实现类里都实现了这个接口
        c.add("how are you?");

        //while 的写法
        Iterator it = c.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        //for 的写法
        for (Iterator it2 = c.iterator();it2.hasNext();){
            System.out.println(it2.next());
        }
    }
}

1.List集合

有序,有下标,可重复

List接口继承了Collection接口,Collection集合中有的方法,List集合也有

ArrayList

import java.util.ArrayList;
public class TestList {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();

        //添加元素
        list.add('h');
        list.add('e');
        list.add('l');
        list.add('l');
        list.add('o');
        //访问元素
        System.out.println(list.size());//集合大小,有多少数组 5
        //list.get(i); 通过下标访问
        for (int i= 0;i<list.size();i++){
            System.out.println(list.get(i));
            /*
            * h
            * e
            * l
            * l
            * o
            * */
        }
        //修改元素
        list.set(1, "o"); // 第一个参数为索引位置,第二个为要修改的值
        System.out.println(list);//[h, o, l, l, o]
        //删除元素
        list.remove(3); // 删除第四个元素
        System.out.println(list);//[h, o, l, o]
    }
}
方法描述
add将元素插入到指定位置的 arraylist 中
addAll添加集合中的所有元素到 arraylist 中
clear()删除 arraylist 中的所有元素
clone()复制一份 arraylist
contains()判断元素是否在 arraylist
get()通过索引值获取 arraylist 中的元素
indexOf()返回 arraylist 中元素的索引值
removeAll()删除存在于指定集合中的 arraylist 里的所有元素
remove()删除 arraylist 里的单个元素
size()返回 arraylist 里元素数量
isEmpty()判断 arraylist 是否为空
subList()截取部分 arraylist 的元素
set()替换 arraylist 中指定索引的元素
sort()对 arraylist 元素进行排序
toArray()将 arraylist 转换为数组
toString()将 arraylist 转换为字符串
ensureCapacity()设置指定容量大小的 arraylist
lastIndexOf()返回指定元素在 arraylist 中最后一次出现的位置
retainAll()保留 arraylist 中在指定集合中也存在的那些元素
containsAll()查看 arraylist 是否包含指定集合中的所有元素
trimToSize()将 arraylist 中的容量调整为数组中的元素个数
removeRange()删除 arraylist 中指定索引之间存在的元素
replaceAll()将给定的操作内容替换掉数组中每一个元素
removeIf()删除所有满足特定条件的 arraylist 元素
forEach()遍历 arraylist 中每一个元素并执行特定操作

LinkList

作为线性表,易增删,不易查改

LinkedList和ArrayList用的时机

频繁访问列表中某一元素,只需在列表末尾进行增删操作,频繁的查询修改--------------------ArrayList

频繁进行添加,删除操作--------------------------------------------------------------------------------------LinkedList

import java.util.LinkedList;

public class TestLinkedList {
    public static void main(String[] args) {
        LinkedList ll = new LinkedList();
        //添加元素
        ll.add("hello");
        ll.add("how");
        ll.add("old");
        ll.add("are");
        ll.add("you");
        System.out.println(ll);//LinkedList也重写了toString方法 [hello, how, old, are, you]
        //在表头添加元素
        ll.addFirst("oh!");
        System.out.println(ll);//[oh!, hello, how, old, are, you]
        //在表尾添加元素
        ll.addLast("?");
        System.out.println(ll);//[oh!, hello, how, old, are, you, ?]

        //移除表头元素
        ll.removeFirst();
        System.out.println(ll);
        //移除表尾元素
        ll.removeLast();
        System.out.println(ll);

        //获取表头元素
        System.out.println(ll.getFirst());
        //也可以通过下标获取表中元素,效率慢~
        System.out.println(ll.get(2));
        //获取表尾元素
        System.out.println(ll.getLast());
    }
}

2.Set集合

无序,不可重复

HashSet

HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。底层数据结构是哈希表。

特点

  • 无序,不重复
  • 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。
  • 允许有 null 值。
import java.util.HashSet;

public class TestHashSet {
    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<String>();
        // add方法添加元素
        hashSet.add("Hello");
        hashSet.add("My");
        hashSet.add("name");
        hashSet.add("is");
        hashSet.add("Li Hua");
        System.out.println(hashSet);//HashSet重写了toString 方法[Hello, Li Hua, name, is, My]
        hashSet.add("Li Hua");//重复元素不被添加
        System.out.println(hashSet);//[Hello, Li Hua, name, is, My]

        //判断元素是否存在
        System.out.println(hashSet.contains("name"));//true
        //删除元素
        hashSet.remove("Li Hua");//传具体要删的值
        System.out.println(hashSet);//[Hello, name, is, My]

        //使用foreach()遍历
        for ( String s :hashSet){
            System.out.println(s);
            /*
            * Hello
            * name
            * is
            * My
            * */
        }
            //全部删除
        hashSet.clear();
        System.out.println(hashSet);//[]
    }
}

内部存储机制

当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。如果有两个元素通过equals方法比较true,但它们的hashCode方法返回的值不相等,HashSet将会把它们存储在不同位置,依然可以添加成功。
也就是说。HashSet集合判断两个元素的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode方法返回值也相等。

靠元素重写hashCode方法和equals方法来判断两个元素是否相等,如果相等则覆盖原来的元素,依此来确保元素的唯一性

3.Map集合

键值对集合

HashMap

  • 是一个散列表,它存储的内容是键值对(key-value)映射。
  • 实现现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
  • 无序
import java.util.HashMap;

public class TestHashMap {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        //添加键值对,put关键字
        hashMap.put(1,"hello");//数字:字符串
        hashMap.put(2,"you");
        hashMap.put(3,"are");
        hashMap.put(4,"my");
        hashMap.put(5,"friend");
        hashMap.put(6,null);
        System.out.println(hashMap);//HashMap重写了toString 方法{1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null}
        hashMap.put("seven","hahaha");//字符串:字符串
        System.out.println(hashMap);//{1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}
        hashMap.put(null,"test");
        System.out.println(hashMap);//{null=test, 1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}
        hashMap.put(null,"emm");//把之前的test覆盖了
        System.out.println(hashMap);//{null=emm, 1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}

        //访问元素 get(key)得到value
        System.out.println(hashMap.get(null));//emm
        System.out.println(hashMap.get(3));//are
        System.out.println(hashMap.get("seven"));//hahaha

        //删除元素 remove(key) 删除键值对
        hashMap.remove(null);
        System.out.println(hashMap);//{1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}
        //删除所有 clear()
        hashMap.clear();
        System.out.println(hashMap);//{}

        //遍历hashMap
        HashMap<Integer,String> hashMap2 = new HashMap<Integer,String>();
        hashMap2.put(1,"hello");//数字:字符串
        hashMap2.put(2,"you");
        hashMap2.put(3,"are");
        hashMap2.put(4,"my");
        hashMap2.put(5,"friend");
        hashMap2.put(6,null);
        // 输出 key 和 value
        for (Integer i : hashMap2.keySet()) {
            System.out.println("key: " + i + " value: " + hashMap2.get(i));
            /*
            key: 1 value: hello
            key: 2 value: you
            key: 3 value: are
            key: 4 value: my
            key: 5 value: friend
            key: 6 value: null
            */
        }
        // 返回所有 value 值
        for(String value: hashMap2.values()) {
            // 输出每一个value
            System.out.print(value + ", ");
            //hello, you, are, my, friend, null,
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值