zoukankan      html  css  js  c++  java
  • 关于JDK中的集合总结(一)

    静态方法只能继承,不能重写(Override).

    StringBufffer数组对象 都是容器。

    加入数据,“zhangsan” true ,67, 三个数据数据类型不同,不能用数组作为集合,只能用StringBuffer或者是StringBuilder作为集合,但是这两个类型,最终转换成字符串才可以使用

    上面的数据封装成StringBuilder为“zhangsantrue67”.

    李四,23,都是(一个对象的)属性值所以用对象来封装,进行存储。

    数值有很多的话可以用数组存储数组有很多的话用二维数组进行存储, 数据有很多的话可以用对象存储对象有很多的话用集合存储.(集合是能存储对象的对象)

    集合中实际上存储的是地址,对象已经创建完了,存储用地址。集合中地址是怎么存放的那就不一定了,每中容器有各自不同的特点。

    数组能存储Person对象吗?可以,类类型的数组。

    但是人的数量可以是变化的,数组是固定长度的,集合是可变长度的。

    集合类的由来:

             对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定, 就使用集合容器进行存储。     

    集合特点:

    1,用于存储对象的容器。

    2,集合的长度是可变的。

    3,集合中不可以存储基本数据类型值。

    部分容器有一些共性,就不断的向上抽取。对体系的使用就是“看顶层用底层”.

    集合类是属于java中的工具,在java.util包中。

    迭代器:取出集合中元素的方式。

    集合容器因为内部的数据结构不同,有多种具体容器,不断的向上抽取,就形成了集合框架。

    框架的顶层Collection接口:

    Collection中的常见方法:

     1,添加。

             boolean add(Object obj):

             boolean addAll(Collection coll):

    2,删除。

             boolean remove(object obj):

             boolean removeAll(Collection coll);

             void clear();

    3,判断:

             boolean contains(object obj):

             boolean containsAll(Colllection coll);

             boolean isEmpty():判断集合中是否有元素。

     4,获取:

             int size():

             Iterator iterator():取出元素的方式:迭代器。

     该对象必须依赖于具体容器,因为每一个容器的数据结构都不同。

     所以该迭代器对象是在容器中进行内部实现的。

     对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是iterator方法。

     Iterator接口就是对所有的Collection容器进行元素取出的公共接口.( 其实就是抓娃娃游戏机中的夹子!)

    5,其他:

             boolean retainAll(Collection coll);取交集。

             Object[] toArray():将集合转成数组。

    集合类的由来:

             对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定, 就使用集合容器进行存储。

    coll.add("abc1");

    coll.add("abc2");

    coll.add("abc3");

    System.out.println(coll);

    集合可以这样直接打印,打印的结果是: [abc1, abc2, abc3]  集合中重写了toString()方法.

    retainAll 保留和指定集合相同的元素在当前元素中.

    removeAll 正好和retainAll相反,删除和指定集合相同的元素在当前元素中.

     //使用了Collection中的iterator()方法。 调用集合中的迭代器方法,是为了获取集合中的迭代器对象。

        Iterator it = coll.iterator();        
        while(it.hasNext()){
            System.out.println(it.next());
        }

     和

        for(Iterator it = coll.iterator(); it.hasNext(); ){
                System.out.println(it.next());
        }

     这两种使用迭代器的方法.第一种在while循环用完迭代器之后还可以继续使用(如果不用的话就是浪费内存)第二种方式老外经常使用,他们不浪费一点内存.开发用第二种.

    Collection

             |--List:有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。

             |--Set:元素不能重复,无序。

    List:特有的常见方法:有一个共性特点就是都可以操作角标。

    1,添加

             void add(index,element);

             void add(index,collection);

    2,删除;

             boolean remove(index);

            boolean remove(Object o); 从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。如果列表不包含元素,则不更改列表

       void clear() ;从列表中移除所有元素

    3,修改:

             Object set(index,element);

    4,获取:

             Object get(index);//Collection的子类中只有List有这个多余的方法来获取,其他子类没有.

             int indexOf(object);

             int lastIndexOf(object);

             List subList(from,to);(注意是不包含尾角标的,和前面的一个方法是一样的道理)

    list集合是可以完成对元素的增删改查。

    ListDemo3.java

     1 public class ListDemo3 {
     2     public static void main(String args[]){
     3         List list = new ArrayList();
     4         list.add("abc1");
     5         list.add("abc2");
     6         list.add("abc3");
     7         
     8         Iterator it = list.iterator();
     9         while(it.hasNext()){
    10             Object obj = it.next();
    11             if(obj.equals("abc2")){
    12                 list.add("abc9");
               //在迭代器过程中,不要使用集合操作元素,容易出现异常。
               //可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。 
    13 } 14 else{ 15 System.out.println("next:"+obj); 16 } 17 } 18 System.out.println(list); 19 } 20 }

    结果输出:

    next:abc1

    Exception in thread "main" java.util.ConcurrentModificationException

    当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

    为什么会出现这种情况呢?

    元素”abc9”添加进来,迭代器是不知道的,因为现在是迭代器在操作这些元素。在迭代器操作的过程中,你又在用集合在操作这个元素。

    集合和迭代器同时在对元素进行修改就会出现问题。

    该如何解决?

    原始的Iterator就只有三个功能, hasNext(),next(),remove();有局限性,没有添加的功能

    那在迭代的过程中添加元素怎么办?

    Iterator的子接口ListIterator就丰富了这个功能,有更多的功能。

    ListIterator it = list.listIterator();//获取列表迭代器对象
    //它可以实现在迭代过程中完成对元素的增删改查。
    //注意:只有list集合具备该迭代功能.所以叫ListIterator
            
    while(it.hasPrevious()){
        System.out.println("previous:"+it.previous());
    }

    如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。 

    ListIterator<E>

    listIterator()
              返回此列表元素的列表迭代器(按适当顺序)。

     ListIterator<E>

    listIterator(int index)
              返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

    容器之所以可以区分就是因为他们内部的存储结构是不一样的。

    List:

             |--Vector:内部是数组数据结构,是同步的。增删,查询都很慢!

             |--ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。

             |--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。

    Vector

    从 Java 2 平台 v1.2 开始,此类改进为可以实现 List 接口,使它成为 Java Collections Framework 的成员。与新 collection 实现不同,Vector 是同步的。

    从以下版本开始:

    JDK1.0 (元老级,很早就出现了)

    现在几乎不用vector了那遇到多线程的程序怎么办呢?那就给ArrayList加锁使用(把添加和删除的方法放在同一个锁中就可以了)。现在几乎不用vector了。

    ArrayList  :List 接口的大小可变数组的实现。

    Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。

    数组不是固定长度吗?

    集合怎么实现不断向里面添加元素?

    是用可变长度数组原理。创建新数组,将原来数组中的内容都复制到新数组中来。

    Vector是百分之百延长.

    ArrayList是百分之五十延长,相比Vector既浪费空间又浪费效率。

    ArrayList 内部是数组,是一片连续的空间,所以查找很快。

    附录一些源码:

    关于ArrayList.class中内部存储元素数组的增长

     1     /**
     2      * Increases the capacity to ensure that it can hold at least the
     3      * number of elements specified by the minimum capacity argument.
     4      *
     5      * @param minCapacity the desired minimum capacity
     6      */
     7     private void grow(int minCapacity) {
     8         // overflow-conscious code
     9         int oldCapacity = elementData.length;
    10         int newCapacity = oldCapacity + (oldCapacity >> 1);
    11         if (newCapacity - minCapacity < 0)
    12             newCapacity = minCapacity;
    13         if (newCapacity - MAX_ARRAY_SIZE > 0)
    14             newCapacity = hugeCapacity(minCapacity);
    15         // minCapacity is usually close to size, so this is a win:
    16         elementData = Arrays.copyOf(elementData, newCapacity);
    17     }

    如果增加的元素超过了10个,那么ArrayList底层会新生成一个数组,长度为原数组的1.5倍+1.

    然后将原数组的内容复制到新数组中,并且后续增加的内容都会放到新数组当中.当新数组无法

    容纳增加的元素时,重复该过程.

    同理LinkedList因为元素在内存中不是连续的是分散的所以查询很慢。

    LinkedList有角标吗?

    有角标,是List的子类。LinkedList本身不是数组,是链表结构,也是有角标的。虽然他们都有编号,但是就是在内存连续与否造成的查询和增删的快慢。

    作业:

    1,自己去查文档演示Vector中的elements()方法。

    2,LinkedList中的,addFirst addLast getFirst,getLast  removeFirst removeLast。

    3,既然集合是存储对象的,请定义ArryaList集合,并存储Person对象。如new Person("lisi",20);

    并取出。将姓名和年龄打印出来。

  • 相关阅读:
    C++解析一些我们需要的数据
    C语言0数组、柔性数组使用介绍
    正点原子T100智能焊台-试用-拆机测评
    简单工厂模式、工厂模式、抽象工厂模式比较
    一次小模块的使用过程-LC12S无线模块介绍
    正点原子DS100拆解全过程-硬件工程师必备
    STM32通过rosserial接入ROS通讯开发
    Linux下实现Firewalld Net 外网端口转发至内网
    Windows中使用netsh portproxy端口转发
    低延迟网穿透工具FRP
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/4321421.html
Copyright © 2011-2022 走看看