JavaSE学习笔记(9)

Day 9

集合类

集合的概念

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

  • 数组的缺点: 数组一旦定义,长度将不能再变化

  • 在开发的过程中,需要使用能够动态增长长度的容器来保存数据,而且我们需要对数据的保存的逻辑可能各种各样,于是就有了各种各样的数据结构。Java中对于各种数据结构的实现,就是我们用到的集合

集合与数组的区别

长度区别 : 集合长度可变,数组长度不可变

内容区别 : 集合可以存储不同类型的元素,数组只能存储单一类型的元素

元素区别 : 集合只能存储引用类型元素,数组可存储引用类型,也可存储基本类型

集合体系概述

JavaSE学习笔记(9)

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

Java集合要从两大接口说起,一为Collection接口,二为Map接口,它们是同一个层次的。

Collection接口

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

    ● Set 中的数据对象没有顺序且不可以重复。
    ● List 中的数据对象有顺序且可以重复。

  • Collection 接口下定义的通用方法:

    • add(E e)添加元素; clear()清空元素; remove(E e)移除元素; size()元素数量;

      toArray()集合转数组; contains(E e)判断元素是否存在; isEmpty()判断集合是否为空;

List

List继承了Collection接口,有三个实现的类
- ArrayList
数组列表,数据采用数组方式存储。
-LinkedList
链表
-Vector
数组列表,添加同步锁,线程安全

  • ArrayList实现类

  • 数据结构:数组;

  • 特点:查询快,增删慢,主要用于查询遍历数据,为最常用集合之一;

JavaSE学习笔记(9)

  • 数组结构是有序的元素序列,在内存中开辟一段连续的空间,在空间中存放元素,每个空间都有编号,通过编号可以快速找到相应元素,因此查询快;数组初始化时长度是固定的,要想增删元素,必须创建一个新数组,把源数组的元素复制进来,随后源数组销毁,耗时长,因此增删慢。

    ArrayList方法代码演示

    public static void main(String[] args){
    Collection<String> s= new ArrayList<String>(); //在<> 中传入了参数"String" 则以后传入的全都是String类型
            //s.add(1); 非String类型 报错
              s.add("1");
              s.add("2");
              s.add("abc");
              Object []objs1 = s.toArray(); //第二个括号里面不加参数指定转换的类型会自动上升为object类型
            System.out.println(Arrays.toString(objs1));//object类型的数组
    
    
              String []objs2 = s.toArray(new String[c.size()-1]);//加入参数String 转换为String类型数组
            System.out.println(Arrays.toString(objs2));
              /*
              集合的方法
               */
    //        s.clear();//清除所有元素
    //        System.out.println(s);
            s.remove("abc");//清除指定位置的指定元素
            System.out.println(s.remove("1"));//会有返回值,true 表示成功清除,false 表示没有找到该元素
    
            System.out.println(s.contains(1));//判断是否包含该元素
            System.out.println(s.contains("2"));
    
    
            System.out.println(s.isEmpty());//判空 如果为空则返回true;
    
            System.out.println(s.size());//返回长度
        }
    
     System.out.println(c.containsAll(c1));//判断c中是否完全包含c1
            c.retainAll(c1); //只保留c中与c1相交部分
            System.out.println(c);
    
    
  • Linklisted实现类

  • 数据结构:链表;

  • 特点:查询慢,增删快;

JavaSE学习笔记(9)

  • 链表分为单向和双向,就是一条链子和两条链子的区别;多出的那条链子记录了元素的顺序,因此单向链表结构无序,双向链表结构有序;链表结构没有索引,因此查询慢;链表的增删只需在原有的基础上连上链子或切断链子,因此增删快。

  • 特有方法:getFirst() 返回开头元素; getLast() 返回结尾元素;pop() 从所在堆栈中获取一个元素; push(E e) 将元素推入所在堆栈;

    addFirst(E e) 添加元素到开头,头插; addLast(E e) 添加元素到结尾,尾插;

    LinkedListed方法代码演示

     public static void main(String[] args) {
            LinkedList<String> llk = new LinkedList<String>();
            //链表和线性表的差别 : 线性表遍历较为方便但是从在中间插入删除比较麻烦,需要将其
            // 中的元素往后面或者前面依次移动,
            //链表插入比较简单,链表具有数据域一个头指针和一个尾指针,尾指针指向下一个头指针,数据域用来存储数据信息。
            //所以在中间插入只需要更改头指针和尾指针的地址即可,而如果遍历的话(llk.get())会判断传入的
    //        索引和size/2进行比较,如果小于则从头开始遍,如果大于则从后向前遍历。
            llk.add("1");
            llk.add("2");
            llk.add("3");
            llk.add("1");
            llk.add("2");
            llk.add("3");
            llk.add("1");
            llk.add("2");
            llk.add("3");
            llk.add("1");
            llk.add("2");
            llk.add("3");
            llk.add("1");
            llk.add("2");
            llk.add("3");
    
            System.out.println(llk);
            System.out.println(llk.get(14));
            System.out.println(llk.get(7));
            System.out.println(llk.getFirst());
            System.out.println(llk.getLast());
            System.out.println(llk.remove(10));
            System.out.println(llk);
    
        }
    
  • Vector实现类

  • 数据结构:数组;

    特点:查询快,增删慢

    和ArrayList一样,都是数组实现,因此具有相似的特性,它们之间的区别在于Vector是线程安全的,效率低,ArrayList是线程不安全的,但效率高。

Set接口

  • Set接口继承了collection接口,有两个实现类
    - Hashset

  • HashSet类中的元素不能重复,即彼此调用equals方法比较,都返回false

  • 底层数据结构是哈希表+链表哈希表依赖于哈希值存储

    -TreeSet

  • 可以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口

  • TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)

  • Hashset实现类

    数据结构:哈希表(数组+单向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树。

    特点:查询快,元素序,元素不可重复,没有索引;

    哈希表底层用数组+单向链表实现,即使用链表处理冲突,同一Hash值的元素都存储在一个链表里,但是当位于一个链表中的元素较多,即Hash值相等的元素较多,通过key值依次查找的效率降低。JDK1.8之后,哈希表底层采用数据+单向链表+红黑树实现,当链表长度超过阈值(8)时,链表将转换为红黑树,极大缩短查询时间。

    哈希值是一个十进制的整数,是对象的地址值,是一个逻辑地址,不是实际存储的物理地址,由系统随机给出。Object类的int hashCode()方法,可以获取对象的哈希值。

    HashSet方法代码演示

    import java.util.HashSet;
    import java.util.Iterator;
    
    public class hash_demo {
    
        @Override
        public String toString() {
            return super.toString();
        }
    
        public static void main(String[] args) {
    
            HashSet<String> hs = new HashSet<String>();
            hs.add("123");
            hs.add("123");
            hs.add("df");
            hs.add("d");
    
            System.out.println(hs);
    //        hs.clear();  清除哈希表中的所有元素
              hs.isEmpty();//判空
              hs.size();//得到哈希表长度
    //        hs.remove(Object obj); 删除Set集合中的元素,删除成功返回true,否则返回false
    //        hs.contains(Object o);判断是否包含某元素
    //        hs.iterator; 迭代器
            Iterator<String> ite = hs.iterator();
            while(ite.hasNext()) {
                System.out.println(ite.next());
            }
    
    
    //        HashSet<test_class> hs2 = new HashSet<test_class>();
    //        test_class t1 = new test_class("test",1);
    //        test_class t2 = new test_class("test",2);
    //        test_class t3 = new test_class("test",3);
    //        test_class t4 = new test_class("test",4);
    //
    //        hs2.add(t1);
    //        hs2.add(t2);
    //        hs2.add(t3);
    //        hs2.add(t4);
    
    
    //        System.out.println(hs2);//new 出来的对象的地址是不同的所以不重写方法就不能判断是否重复
    
        }
    }
    
    
  • TreeSet实现类

    数据结构:红黑树

    特点:查询快,元素序,元素不可重复,没有索引;

    底层分析:TreeSet实现了继承于Set接口的SortedSet接口 ,它支持两种排序方法,自然排序和定制排序,自然排序的意思就是放入元素“a”,“b”,a会自然地排在b前面,其中还有几个特有方法。

    first() 返回第一个元素; last() 返回最后一个元素;comparator() 返回排序比较器;

    TreeSet方法代码演示

    import sun.reflect.generics.tree.Tree;
    
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.TreeSet;
    
    public class TreeSetDemo{
        public static void main(String[] args) {
            TreeSet<Integer> ts = new TreeSet<>();
                            ts.add(-5);
                            ts.add(2);
                            ts.add(3);
                            ts.add(1);
                            ts.add(-8);
                            ts.add(1);
    
            System.out.println(ts);
    //        TreeSet 底层实现为自平衡二叉树(红黑树) 自动排序
    //      ts.clear();  清除哈希表中的所有元素
            ts.isEmpty();//判空
            ts.size();//得到哈希表长度
    //      ts.remove(Object obj); 删除Set集合中的元素,删除成功返回true,否则返回false
    //      ts.contains(Object o);判断是否包含某元素
    //      ts.iterator(); 迭代器
            ts.iterator();
            Iterator<Integer> ite= ts.iterator();
            while(ite.hasNext()){
                System.out.println(ite.next());
            }
    //
    //        Car car1 = new Car(10,"car1");
    //        Car car2 = new Car(8,"car2");
    //        Car car3 = new Car(0,"car3");
    //        Car car4 = new Car(-10,"car4");
    //        Car car5 = new Car(5,"car5");
    //
    //        TreeSet<Car> tset2 = new TreeSet<>();
    //        tset2.add(car1);
    //        tset2.add(car2);
    //        tset2.add(car3);
    //        tset2.add(car4);
    //        tset2.add(car5);
    //
    //       Iterator<Car> ite= tset2.iterator();
    //       while(ite.hasNext()){
    //           System.out.println(ite.next());
    //       }
    
        }
    }
    
    
上一篇:JavaSE 第一天作业


下一篇:【JavaSE】 ArrayList与顺序表