栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java集合

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java集合

1.集合与数组的关系及其概述 1.1集合与数组都是容器

集合和数组都是对多个数据进行存储操作的结构,简称Java容器。

注意:此时的存储是内存层面的存储,而非持久化的存储。

1.2数组存储的特点与缺点

数组存储的特点:1)一旦初始化之后,其长度就确定了;2)数组一旦定义好,其元素的类型也就确定了,我们也就只能操作指定类型的数据。

数组存储的缺点:1)一旦初始化之后,其长度就不可修改;2)数组中提供的方法十分有限;3)若想获取数组中实际元素的个数,没有现成的属性和方法可用;4)数组存储的是有序、可重复的数据,无法满足无序、不可重复数据的存储需求。

1.3集合框架

Java集合可分为Collection体系和Map体系

<1>Collection接口:单列数据,定义了存取一组对象的方法的集合

    1)List接口:元素有序,可重复的集合,(习惯上称为“动态数组” );→常用实现类:ArrayList,linkedArrayList,Vector。

   2)Set接口:元素无序,不可重复的集合;→常用实现类:HashSet,linkedHashSet,TreeSet。

   3)Quene接口。

<2>Map接口:双列数据,保存具有映射关系的“key-value对”的集合。→常用实现类:HashMap,linkedHashMap,TreeMap,Hashtable,Properties。

2.Collection接口常用的方法

注意:向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals()。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class CommonlyUsedMethod
{
    public static void main(String[] args)
    {
        Collection coll=new ArrayList();
        
        System.out.println("1.add(Object e)的使用");
        coll.add(1234);
        coll.add("aaa");

        
        System.out.println("2.size()的使用");
        System.out.println(coll.size());//输出2

        
        System.out.println("3.addAll(Collection coll)的使用");
        Collection coll2=new ArrayList();
        coll2.addAll(coll);
        coll2.add(5678);
        System.out.println(coll2.size());//输出3
        System.out.println(coll2);//输出集合coll2中的元素:[1234, aaa, 5678]

        
        System.out.println("4.isEmpty()的使用");
        System.out.println(coll2.isEmpty()); //输出false

        
        System.out.println("5.clear()的使用");
        coll.clear();
        coll2.clear();

        
        System.out.println("6.contains(Obkect o)的使用");
        coll2.add(123);coll2.add(456);coll2.add(true);coll2.add(new String("Tom"));
        System.out.println(coll2.contains(123));//输出true
        System.out.println(coll2.contains(new String("Tom"))); //输出true,这里其实又造了一个String对象,由此可见查看是否包含有元素,调的是当前类的equals()方法

        
        System.out.println("7.containsAll(Collection coll)的使用");
        coll.add(123);coll.add(true);
        System.out.println(coll2.containsAll(coll)); //输出true

        
        System.out.println("8.remove(Object o)的使用");
        System.out.println(coll2); //输出[123, 456, true, Tom]
        System.out.println(coll2.remove(456)); //输出true
        System.out.println(coll2); //输出[123, true, Tom]

        
        System.out.println("9.removeAll(Collection coll)的使用");
        System.out.println(coll); //输出[123, true]
        coll2.removeAll(coll);
        System.out.println(coll2);//输出Tom

        
        System.out.println("10.retainAll(Collection coll)的使用");
        coll.add(456);coll.add(789);
        System.out.println(coll);//coll为:[123, true, 456, 789]
        coll2.add(456);coll2.add(789);
        System.out.println(coll2);//coll2为:[Tom, 456, 789]
        System.out.println(coll2.retainAll(coll));//输出true
        System.out.println(coll2);//此时,coll2为:[456, 789]

        
        System.out.println("11.equals(Object o)的使用");
        Collection coll3=new ArrayList();
        coll3.add(456);coll3.add(789);
        System.out.println(coll2.equals(coll3));//输出true
        Collection coll4=new ArrayList();
        coll4.add(789);coll4.add(456);
        System.out.println(coll2.equals(coll4));//输出false,因为这里ArrayList需要有序

        
        System.out.println("12.hashcode()的使用");
        System.out.println(coll2.hashCode());//输出15886

        
        System.out.println("13.toArray()的使用");
        Object[] arr=coll2.toArray();
        for (Object o: arr)
        {
            System.out.println(o);//遍历输出数组arr中的(其实也是coll2中的)的元素
        }

        
        System.out.println("14.Array中的asList方法");
        String[] strs=new String[]{"qwer","tyui","asdf"};
        List strings = Arrays.asList(strs);
        System.out.println(strings);

        
    }
}
3.集合元素的遍历 3.1使用迭代器Iterator接口遍历集合

<1>迭代器模式

访问容器对象中的各个元素,而又不暴露该对象的内部细节,主要用于遍历Collection中的元素。

iterator()仅用于遍历集合,且集合对象每次调用iterator(),都会得到一个全新的迭代器对象,默认游标在集合的第一个元素之前。

<2>迭代器的hasNext()和next()方法

hasNext():boolean→以当前位置为基础,判断下一位置是否还有元素

next():E→指针下移,并将下移以后集合位置上的元素返回。

代码:

对于代码中的“Iterator iterator=coll.iterator();”这一句,是因为集合中的iterator()方法返回的是Iterator接口的对象,其实际过程为:ArrayList实现类中定义了一个内部类Itr,Itr实现了Iterator接口,即“private class Itr implemens Iterator”,重写了其中的next(),hasNext()等方法,这里的iterator()方法的方法体中只有一句,即:“return new Itr();”,所以当调用iterator()方法时,得到的是Iterator接口实现类的对象。

@Test
public void nextAndhasNextTest()
    {
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(new Person("Jerry", 20));
        coll.add(new String("Tom"));
        coll.add(false);
        Iterator iterator = coll.iterator();
        while (iterator.hasNext())
        {
            System.out.println(iterator.next());
        }
    }

<3>一种用迭代器遍历集合的错误示范

//下面这样写会出现错误,陷入死循环,不断输出集合的第一个元素123
//原因是因为:集合对象每次调用iterator()方法都得到一个全新的迭代器对象!!
//        while(coll.iterator().hasNext())
//        {
//            System.out.println(coll.iterator().next());
//        }

<4>迭代器的remove()方法(注意这是迭代器哦的remove方法)

remove():void  →删除当前迭代器所在位置的元素

注意:如果还未调用next()或在上一次调用next()方法后已经调用了remove()方法,再调用remove()都会报IIlegalStateException异常。

@Test
        public void removeTest()
        {
            Collection coll = new ArrayList();
            coll.add(123);
            coll.add(new Person("Jerry", 20));
            coll.add(new String("Tom"));
            coll.add(false);
            Iterator iterator1 = coll.iterator();
            while (iterator1.hasNext())
            {
                Object o = iterator1.next();
                if ("Tom".equals(o))
                {
                    iterator1.remove();
                }
            }
            iterator1=coll.iterator();//因为上面的while循环使得iterator1指向了最后的位置,所以这里重置一下
            while (iterator1.hasNext())
            {
                System.out.println(iterator1.next());
            }
        }
3.2使用增强for循环遍历集合

<1>快捷键:集合名.for 或者 iter

<2>格式: for(集合中元素的类型   局部变量名:集合对象名) {......}

<3>其内部实质上仍调用了迭代器

<4>增强for循环不会改变原有集合中元素的值

4.Collection子接口之——List接口 4.1List接口概述

<1>List集合类中元素有序,且可重复,每个元素都有其对应的顺序索引;

<2>List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素;

<3>List接口的三个常用类:ArrayList,linkedList,Vector的异同

同:都实现了List接口,存储数据的特点相同:即有序,可重复的数据

异:1)ArrayList:线程不安全,效率高,底层使用Object[] elementData存储;2)linkedList:对于频繁地插入、删除操作,使用linkedList比使用ArrayList的效率要高,底层使用双向链表存储;3)Vector:是List接口的古老实现类,线程安全,效率低,底层使用Object[] elemenData存储。

4.2ArrayList源码分析

ArrayList底层使用了数组Object[] elementData

<1>▲▲jdk7情况下:

1)就ArrayList的初始化而言,ArrayList list=new ArrayList() //底层创建了长度是10的Object[]数组,数组名为elementData

具体情况为:ArrayList.java中存在代码:

    private transient Object[] elementData;
    public ArrayList (int initialCapacity)
    {
        super();
        if(initialCapacity<0)
            throw new IllegalArgumentException("Illegal Capacity:"+initialCapacity);
        this.elementData=new Object[initialCapacity];
    }
    public ArrayList()
    {this(10);}//当使用空参构造器造ArrayList对象时,定义了一个容量为10的Object型数组

2)就ArrayList添加元素而言

list.add(1); //相当于elementData[0]=new Integer(1);

.......................

list.add(11);// 若此次的添加导致底层的elementData数组容量不够,则需扩容,默认情况下扩容为原来的1.5倍。同时,需将原有数组中的数据复制到新的数组中。

结论:建议开发中使用带参的构造器

<2>▲▲jdk8情况下

ArrayList list=new ArrayList(); //底层Object[] elementData初始化为{},并没有创建长度为10的数组

list.add(1);// 当第一次调用add()方法时,底层才创建了长度为10的数组,并将数据1添加到elementData数组的第一个位置上,后续的添加与扩容与jdk7无异。

<3>jdk7中ArrayList对象的创建类似于单例模式的饿汉式,而jdk8中ArrayList对象的创建类似于单例模式的懒汉式,这延迟了数组的创建,节省了内存。

4.3linkedList源码分析

linkedList list=new linkedList(); //内部声明了Node类型的first和last属性,默认值为null

list.add(123); //将123封装到Node中,创建了Node对象

其中,Node定义为:

private static class Node
    {
        E item;
        Node next;
        Node prev;
        Node(Node prev,E element,Node next)
        {
            this.item=element;
            this.next=next;
            this.prev=prev;
        }
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459859.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号