• 集合


    集合框架

    什么是集合:

      集合是Java提供的一种容器,用于存放引用类型的数据。

    集合和数组的区别;

      数组是一种长度不可变的容器,用于存放基本数据类型和引用数据类型。

      集合是一种长度可变的容器,它的实现类多种多样,然后列举图中的实现类的特点 ;只能存放引用数据类型,如果想要存放基本数据类型,必须转化成其对应的包装类才能存放。

    怎么学习集合 ,要从上往下学习

      先学习Collection中的方法

        boolean add(E e)       添加元素
        boolean remove(Object o)   删除元素
        void clear()            清空元素,删除所有
        boolean contains(Object o)    是否包含某个元素
        boolean isEmpty()
        int size()

     1 import java.util.ArrayList;
     2 import java.util.Collection;
     3 
     4 public class MyCollection_Test {
     5 
     6     public static void main(String[] args) {
     7         // 多态,调用的是父类自己的方法,但是父类是接口,调用的是实现类类实现了的方法,但是不能调用实现类特有的
     8         Collection<Student> lists = new ArrayList<>();
     9         lists.add(new Student("张三"));
    10         lists.add(new Student("李四"));
    11         lists.add(new Student("王五"));
    12         // 这样是移除不了的,除非重写equals方法,因为重新new了一个对象,地址是不同的;或者在存放是用一个学生变量接收,这样在删除时就好操作了
    13         System.out.println(lists.remove(new Student("张三"))); //执行结果是false
    14     }
    15 }
    16 
    17 class Student {
    18     private String name;
    19 
    20     public Student(String name) {
    21         super();
    22         this.name = name;
    23     }
    24 
    25 }

     Java集合框架的集合类,我们有时候称之为容器。容器的种类有很多种,比如ArrayList、LinkedList、HashSet...,每种容器都有自己的特点,ArrayList底层维护的是一个数组;LinkedList是链表结构的;HashSet依赖的是哈希表,每种容器都有自己特有的数据结构。

      因为容器的内部结构不同,很多时候可能不知道该怎样去遍历一个容器中的元素。所以为了使对容器内元素的操作更为简单,Java引入了迭代器模式! 

      把访问逻辑从不同类型的集合类中抽取出来,从而避免向外部暴露集合的内部结构。

        1.迭代器Iterator接口的实现方式

          在JDK中它是这样定义的:对Collection进行迭代的迭代器。迭代器取代了Java Collection Framework中的Enumeration。迭代器与枚举有两点不同:

            1. 迭代器在迭代期间可以从集合中移除元素。

            2. 方法名得到了改进,Enumeration的方法名称都比较长。

              其接口定义如下:

    1 package java.util;
    2 public interface Iterator<E> {
    3     boolean hasNext();//判断是否存在下一个对象元素
    4 
    5     E next();//获取下一个元素
    6 
    7     void remove();//移除元素
    8 }

      2.Iterable

      Java中还提供了一个Iterable接口,Iterable接口实现后的功能是‘返回’一个迭代器,我们常用的实现了该接口的子接口有:Collection<E>、List<E>、Set<E>等。该接口的iterator()方法返回一个标准的Iterator实现。实现Iterable接口允许对象成为For…each语句的目标。就可以通过for…each语句来遍历你的底层序列。

      Iterable接口包含一个能产生Iterator对象的方法,并且Iterable被for…each用来在序列中移动。因此如果创建了实现Iterable接口的类,都可以将它用于for…each中。

    Iterable接口的具体实现:

    Package java.lang;
    
    import java.util.Iterator;
    public interface Iterable<T> {
        Iterator<T> iterator();
    }

      遍历方法:

      第一种:(基本原理)

        第一步:实现迭代器   

    1     Iterator it= lists.iterator();

        第二步:使用while循环 while(it.hasNext()){ sysout( it.next()); }

      第二种:(实质还是第一种)

        不用实现迭代器,直接使用for…each输出

    再学习它的子类List接口

     list有类似于数组的操作

      ArrayList---底层是数组
      LinkedList---底层是链表

      Vector--- 底层是数组(现在不怎么被使用,作为了解)
      void add(int index,E element) 添加元素到指定的下标位置
      E remove(int index) 删除指定下标位置的元素(注意这个和父类的移除不一样,这里可以返回自己移除的元素,有一个后悔的机会)
      E get(int index) 获取指定下标位置的元素
      E set(int index,E element) 修改指定下标位置的元素
      ListIterator listIterator() Iterator的增强版 (增强版的迭代器,可以倒序遍历,但是迭代器的指针必须是在最后一个的位置上,否则不可以使用倒序输出,调用方法是 对象名.下面两个方法 
      boolean hasPrevious()
      E previous()

      

      ArrayList:
        底层就是数组:查询快,增删慢
        线程不安全,效率高

      Vector:
        底层就是数组:查询快,增删慢
        线程安全,效率低
        确实需要使用线程安全的ArrayList,也不建议使用,一般使用Collections类的方法

      LinkedList
        底层数据结构是链表,查询慢,增删快
        线程不安全,效率高

    面试常考题:

      List的选择:   

    首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList、Vector和LinkedList。List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。3个具体实现类的相关区别如下:

      1. ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
      2. Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
      3. LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
      4. vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的,而Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。
      5. 如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度
        的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。

      6. 如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist都可以。而
        如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用Linkedlist,因为它移动一个指定位置的数据
        所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。
        ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,
        都允许直接序号索引元素,但是插入数据要设计到数组元素移动 等内存操作,所以索引数据快插入数据慢,
        Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差
        ,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!

      7. 笼统来说:LinkedList:增删改快
                       ArrayList:查询快(有索引的存在)

    再学习Collection接口的另一个子接口Set

    Set接口的实现类

        hashSet的特点:无序且元素不重复,无序指的是添加的顺序和内存中存储的顺序是不一样的,元素不重复指的是元素在栈内存中的地址不重复,在调用add()方法时,内部调用了没有重写的hashCode和equals方法,所以如果是引用类型,就要重写这两个方法。

        hashSet底层的add()方法是调用了Map接口的put(K key,V vaule)方法,key就是HashSet类型的元素,

     public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }

         

        

      

  • 相关阅读:
    solaris 10 root忘记密码的解决方法
    c程序设计--指针与数组
    photoshop之色阶的使用
    Handling Errors Exceptionally Well in C++ 在C++中良好地捕获意外的错误
    自动换行 wordbreak:breakall和wordwrap:breakword
    透明度
    position:fixed在IE6下的实现
    JavaScript教程:常用DOM操作方法,JavaScriptDOM基本操作
    30 个免费的 UI 工具箱
    去掉虚线框兼容所有浏览器
  • 原文地址:https://www.cnblogs.com/19322li/p/10673963.html
Copyright © 2020-2023  润新知