Java集合详解

集合

一、概述

  • 集合、数组都是对多个数据进行存储操作的结构,简称Java容器
  • 说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,数据库中)

二、集合框架

2.1 Collection接口

  • 概述:单列集合,用来存储对象
  • 结构:
    • List接口
    • Set接口
2.1.1 List接口
  • 概述:存储有序的、可重复的数据
  • 实现类:
    • ArrayList类:作为List接口的主要实现类,线程不安全的,效率高,底层使用Object[]数组存储
    • LinkedList类:对于频繁插入、删除操作,使用此类效率比ArrayList高,底层使用双向链表存储
    • Vector类:作为List接口的古老实现类,效率高;底层使用Object[]数组存储
  • 相同点:三个类都实现了List接口,存储数据特点相同
  • ArrayList简单代码练习
public class ListTest {
    @Test
    public void test(){
        ArrayList list =new ArrayList();
        list.add(123);
        list.add(456);
        list.add("AA");
        list.add(new Person("wang",18));
        list.add(456);
        //链表长度
        System.out.println(list.size());
        //删除指定索引处的元素
        System.out.println(list.remove(1));
        System.out.println(list.size());
        System.out.println(list);
        list.add(1,"YSW");
        System.out.println(list);
        //得到指定索引处的元素
        System.out.println(list.get(1));
        System.out.println("-----------------------------------------------------");
        //在指定所引出添加元素
        list.add(1,456);
        //返回第一次出现元素value时的索引
        System.out.println(list.indexOf(456));
        //返回最后出现元素value时的索引
        System.out.println(list.lastIndexOf(456));
        System.out.println(list);
        Object set = list.set(0, 1);
        System.out.println(set);
        System.out.println(list);
        List list1 = list.subList(3, 6);
        System.out.println(list1);
        System.out.println("-----------------------------------------------------");
        //通过迭代器遍历输出元素
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}
  • Iterator迭代器接口练习
public class IteratorTest {
    @Test
    public void test1() {
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add("abc");
        coll.add(456);
        coll.add(false);

        Iterator iterator = coll.iterator();
        //方法一:
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        //报异常:java.util.NoSuchElementException
//        System.out.println(iterator.next());
        //方法二:不推荐
//        for (int i = 0; i <coll.size() ; i++) {
//            System.out.println(iterator.next());
//        }
        //方法三:推荐
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    @Test
    public void test2(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add("abc");
        coll.add(456);
        coll.add(false);
        coll.add("Tom");
        Iterator iterator = coll.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("------------------------------------");
        Iterator iterator1 = coll.iterator();
        while(iterator1.hasNext()){
            Object obj=iterator1.next();
            if("Tom".equals(obj)){
                //移除集合中的元素
                iterator1.remove();
                //iterator1.remove();   调用remove之后再调remove会报:java.lang.IllegalStateException
            }
        }
        Iterator iterator2 = coll.iterator();
        while(iterator2.hasNext()){
            System.out.println(iterator2.next());
        }
    }
}
  • 常用方法练习
public class List {
    @Test
    public void test(){
        Collection coll =new ArrayList();
        //add():
        coll.add("AA");
        coll.add("BB");
        coll.add(123);//自动装箱
        coll.add("Tom");
        coll.add(new Date());
        coll.add(new Person("Ysw",18));
        //size():
        //获取元素个数
//        System.out.println(coll.size());
        Collection coll1=new ArrayList();
        coll1.add("EE");
        coll1.add(345);
        //addAll(coll1):将coll1集合中的元素添加到当前的集合中
        coll.addAll(coll1);
//        System.out.println(coll.size());
//        System.out.println(coll);

        //isEmpty():判断当前集合是否为空
//        System.out.println(coll.isEmpty());
//        //clear():清空集合元素
//        coll.clear();
//        System.out.println(coll.isEmpty());
        boolean contains=coll.contains(123);
        System.out.println(contains);
        System.out.println(coll.contains("Tom"));
        //Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals()。
        System.out.println(coll.contains(new Person("Ysw",18)));
        System.out.println("--------------------------------------------");
        //containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合当中
        System.out.println(coll.containsAll(coll1));
        Collection coll2=Arrays.asList(123,3456);
        System.out.println(coll.containsAll(coll2));
    }
    @Test
    public void test2(){
        Collection coll =new ArrayList();
        coll.add("AA");
        coll.add("BB");
        coll.add(123);//自动装箱
        coll.add(456);
        coll.add("Tom");
        coll.add(new Date());
        coll.add(new Person("Ysw",18));
        //remove(Object obj):
        System.out.println(coll);
        coll.remove("AA");
        coll.remove(new Person("Ysw",18));
        System.out.println(coll);
        Collection coll2=Arrays.asList(123,456,78);
        //removeAll(Collection coll2):从前集合当中移除college中所有元素
//        System.out.println(coll);
//        coll.removeAll(coll2);
//        System.out.println(coll);
        //retainAll(Collection coll2):交集:获取当前集合和coll集合的交集,并且返回给当前集合
        coll.retainAll(coll2);
        System.out.println(coll);
        System.out.println("----------------------------------------");
        //equals(Object obj):判断当前集合和形参集合元素是否相同;
        Collection coll3=Arrays.asList(123,456,78);
        System.out.println(coll2.equals(coll3));
        //hashCode():返回当前对象的哈希值
        System.out.println(coll.hashCode());
        System.out.println("----------------------------------------");
        //集合转换为数组   toArray()
        Object[] arr = coll3.toArray();
        for (int i = 0; i <arr.length ; i++) {
            System.out.println(arr[i]);
        }
        //iterator():返回Iterator接口的实例,用于遍历集合元素。
    }
}

2.1.2 Set接口
  1. 概述

    • 存储无序的,不可重复数据
    • 实现类:HashSet类、LinkedHashSet类、TreeSet类
  2. 无序性(以HashSet为例)

    • 无序性不等于随机性。
    • 存储数据在底层数组中并非按照索引的顺序添加,而是根据数据的哈希值
  3. 不可重复性

    • 保证添加的元素按照equals()判断时,不能返回true。即:相同元素只能添加一个
  4. 添加元素的过程(HashSet为例)

    • 如果此位置上没有元素,则a添加成功
    • 如果此位置有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的哈希值:如果哈希值不相同则元素a添加成功
    • 如果哈希值相同则调用a所在类的equals方法,若方法返回true,则元素添加失败,若返回false则添加成功
    • 注意:HashSet底层是以数组加链表的方式存储的
  5. 代码练习

public class SetTest {
    @Test
    public void test(){
        HashSet set=new HashSet();
        set.add(123);
        set.add(456);
        set.add(123);
        set.add("AA");
        set.add("BB");
        set.add("CCCCC");
        set.add(new Person("haha",18));
        set.add(new Person("haha",18));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    @Test
    public void test2(){
        //LinkedHashSet()作为HashSet的子类,在添加数据时,每个数据还
        // 维护了两个引用,构建了一个链表,便于频繁的遍历操作
        HashSet set=new LinkedHashSet();
        set.add(123);
        set.add(456);
        set.add(123);
        set.add("AA");
        set.add("BB");
        set.add("CCCCC");
        set.add(new Person("haha",18));
        set.add(new Person("haha",18));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    @Test
    public void test3(){
        /**
         * 1、向TreeSet中添加数据要添加相同类的对象
         * 2、两种排序方式:自然排序   定制排序
         */
        TreeSet set=new TreeSet();
        set.add(new Person("Tom",18));
        set.add(new Person("Jack",16));
        set.add(new Person("Jim",20));
        set.add(new Person("Tom",19));
        set.add(new Person("Jerry",30));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    @Test
    public void test4(){
        Comparator com=new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Person&& o2 instanceof Person){
                    Person p1=(Person)o1;
                    Person p2=(Person)o2;
                    return Integer.compare(p1.getAge(),p2.getAge());
                }else{
                    throw new RuntimeException("输入的数据类型不匹配!");
                }
            }
        };
        TreeSet set=new TreeSet(com);
        set.add(new Person("Tom",18));
        set.add(new Person("Jack",16));
        set.add(new Person("Jim",20));
        set.add(new Person("Tom",19));
        set.add(new Person("Jerry",30));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

2.2 Map接口

2.2.1 概述
  1. 概述
    • 双列数据,存储key—value对的数据
  2. 实现类
    • HashMap类:作为Map的主要实现类;线程不安全,效率高;可以存储null的key或value
    • LinkedHashMap类:能够保证遍历Map元素时,可以按照添加的顺序实现遍历。
    • 原因:在原来的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素。对于频繁的遍历操作,此类执行效率比较高。
    • TreeMap类:保证按照添加的 key–value 对进行排序,实现排序遍历。(此时考虑key的自然排序定制排序
    • HashTable:作为古老实现类;线程安全,效率高低。
    • Properties类:常用来处理配置文件。key 和 value都是String类型。
  3. 注意:数组+链表 (jdk7及之前)数组+链表+红黑树(jdk 8
2.2.2 Map集合结构的理解
  1. Map中的key
    • 无序的、不可重复的,使用Set进行存储key
    • 重写equals()和hashCode()方法(以HashMap为例)
  2. Map中的value
    • 无序的、可重复的,使用Collection存储所有的value
  3. 键值对
    • key-value构成了一个Entry对象。 Map中的entry:无序的、不可重复的,使用Set存储所有Entry。
2.2.3 HashMap底层实现原理
  1. 以jdk 7为例
  2. HashMap map = new HashMap()
    • 在实例化以后,底层创建了长度是16的一维数组Entry[] table
  3. map.put(key1,value1):添加元素
    • 调用key1所在类的hashCode()计算key1哈希值,此时哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。
    • 如果此位置上位置为空,则key1和value1添加成功
    • 如果此位置不为空,即此位置上有一个或多个(以链表形式存在)数据,比较key1和已经存在的一个或多个数据的哈希值
    • 如果key1的哈希值与已经存在的哈希值都不相同,此时key1–value1添加成功。(数据以链表形式存储)
    • 如果key1的哈希值和已经存在的某一个元素的哈希值相同,继续比较:调用key1所在类的equals()方法,比较
      • 如果equals()方法返回false:此时key1–value1添加成功。(数据以链表形式存储)
      • 如果equals()返回true:使用value替换相同key的value值。
  4. jdk 8和jdk 7在底层实现的不同
  • new HashMap ():底层没有创建一个长度为16的数组
  • jdk 8底层的数组是:Node[],而不是Entry[]
  • 首次调用put()方法时,底层创建长度为16 的数组
  • jdk 7底层结构只有:数组+链表,jdk 8中底层结构是:数组+链表+红黑树
  • 当数组的某一个索引的位置上的元素以链表形式存在的数据个数>8且当前数组的长度超过>64时,此时索引位置上的所有数据改为红黑树存储
2.2.4 代码示例
public class MapTest {
    @Test
    public void MapTest(){
//        Map map=new Hashtable();
        Map map=new HashMap();
        //添加
        map.put("AA",123);
        map.put("BB",456);
        map.put("CC",789);
        //修改
        map.put("AA",23);
        System.out.println(map);
        Map map1=new HashMap();
        map1.put("DD",123);
        map1.put("EE",456);
        map.putAll(map1);
        System.out.println(map);
        //remove(Object key)
        Object value = map.remove("AA");
        System.out.println(value);
        System.out.println(map);
    }
    @Test
    public void test1(){
        Map map=new HashMap();
        map.put("AA",123);
        map.put("BB",456);
        map.put("CC",789);
        //get(Object key);
        System.out.println(map.get("AA"));
        //containsKey(Object key):
        boolean key = map.containsKey("AA");
        System.out.println(key);
        //
        boolean value = map.containsValue(123);
        System.out.println(value);
    }
    @Test
    public void test2(){
        Map map=new HashMap();
        map.put("AA",123);
        map.put("BB",456);
        map.put("CC",789);
        //遍历所有的key集:keySet()
        Set set = map.keySet();
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("------------------------------------------");
        //遍历所有的value集:values()
        Collection values = map.values();
        for (Object obj:values) {
            System.out.println(obj);
    }
        //遍历所有key-values  entrySet();
        Set set1 = map.entrySet();
        Iterator iterator1 = set1.iterator();
        while(iterator1.hasNext()){
            Object obj=iterator1.next();
            //entrySet集合中的元素都是entry
            Map.Entry entry= (Map.Entry) obj;
            System.out.println(entry.getKey()+"---->"+entry.getValue());
        }
//        System.out.println(map);
    }
}

三、Properties

3.1 概述

  • Properties类是Hashtable的子类,该对象用于处理属性配置文件
  • key和value都是String类型

3.2 代码演示

public class Test {
    public static void main(String[] args) {
        Properties p = new Properties();
        FileInputStream inputStream = null;
        try {
            //获取输入流
            inputStream = new FileInputStream("./src/jdbc.properties");
            p.load(inputStream);
            //通过key得到值
            String user = p.getProperty("user");
            String driver = p.getProperty("driver");
            System.out.println(user + "\n" + driver);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

四、Collections工具类

4.1 概述

  • Collections类提供了操作集合的一些方法

4.2 常用方法

  • 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中对应的值
  • Collections类中提供了多个synchronizedXxx()方法,该方法可以将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ysw!不将就

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值