Java基础-14

来源:互联网 发布:海岛奇兵科技升级数据 编辑:程序博客网 时间:2024/06/14 00:08

Java基础-集合

集合入门

1、集合框架(体系概述)

集合类Collection:

  • 为什么出现集合类?面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象进行操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

  • 数组和集合类同是容器,有何不同?

    数组虽然也可以存储对象,但长度是固定的;集合长度是可以变得,数组中可以存储基本数据类型,集合只能存储对象。
  • 集合类的特点。

    集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
  • 为什么会出现这么多的容器呢?

    因为每一个容器对数据的存储方式都有不同,这个存储方式称之为:数据结构。

集合图:


Collection类属于java.util.*;包中

2、集合框架(共性方法)

import java.util.*;class CollectionDemo{    public static void main(String[]args)    {        method_1();        method_2();    }    public static void method_1()    {        //创建一个集合容器,使用Collection接口的子类ArrayList类                ArrayList al = new ArrayList();                //添加元素到容器al中。                al.add("java01");                al.add("java02");                al.add("java03");                al.add("java04");                //打印容器中的元素                System.out.println("al中有:"+al);                //获取个数,集合长度。                System.out.println("al.size :"+al.size());                //删除元素                al.remove(1);                System.out.println("删除java03是否成功?"+al.remove("java03"));                //清空集合                al.clear();                System.out.println("清空集合后al中有:"+al);                //判断元素                System.out.println("al中是否存在java03?"+al.contains("java03"));                System.out.println("al是否为空?"+al.isEmpty());    }    public static void method_2()    {        ArrayList al1 = new ArrayList();        ArrayList al2 = new ArrayList();        al2.add("java01");        al2.add("java02");        al2.add("java03");        al2.add("java04");        al1.add("java01");        al1.add("java02");        al1.add("java05");        al1.add("java06");        //取交集        al1.retainAll(al2);        System.out.println("al1取了al2的交集后的结果是"+al1);        //去掉相同的子集        al2.removeAll(al1);        System.out.println("al2被去掉了al1中相同的子集后的结果是:"+al2);    }}

输出结果:

al中有:[java01, java02, java03, java04]al.size :4删除java03是否成功?true清空集合后al中有:[]al中是否存在java03?falseal是否为空?trueal1取了al2的交集后的结果是[java01, java02]al2被去掉了al1中相同的子集后的结果是:[java03, java04]

图:


3、集合框架(迭代器)

  • 什么是迭代器?

    其实就是集合取出元素方式。就把取出方式定义在集合内部,这样取出方式就可以直接访问集合内容的元素,那么取出方式就被定义成内部类,而每一个容器的数据结构不同,所以取出的动作细节不一样,但是都有共性内容:判断和取出,那么可以将共性抽取,那么这些内部类都符合一个规则,该规则就是Iterator。
  • 如何获取集合的取出对象呢?

    通过一个对外提供的方式:iterator();


import java.util.*;class CollectionDemo{    public static void main(String[]args)    {        method_get();    }    public static void method_get()    {        ArrayList al = new ArrayList();        al.add("java01");        al.add("java02");        al.add("java03");        al.add("java04");        Iterator it = al.iterator();        while(it.hasNext())        {            System.out.println(it.next());        }        //另一种使用迭代器的方法,可以更省资源        System.out.println();        for(Iterator it1 = al.iterator();it1.hasNext();)//当for循环完毕,Iterator it1 = al.iterator()语句释放        {            System.out.println(it1.next());        }    }}

输出结果:

java01java02java03java04java01java02java03java04

4、集合框架(List集合共性方法)

Collection

|--List:元素是有序的,同时元素可以重复,因为该集合体系有索引

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

List(接口):特有方法:凡是可以操作角标的方法都是该体系特有方法。

  • 增:

    void add(int index,E element);//将指定的元素插入此列表中的指定位置。boolean addAll(int index,Collection c);// 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
  • E remove(int index);// 移除此列表中指定位置上的元素。
  • E set(int index, E element);//用指定的元素替代此列表中指定位置上的元素。
  • E get(int index);//返回此列表中指定位置上的元素。List<E> subList(int fromIndex , int toIndex);//返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。ListIterator<E> listIterator();//返回此列表元素的列表迭代器(按适当顺序)。

演示代码:

import java.util.*;class ListDemo{    public static void main(String[]args)    {        ArrayList al = new ArrayList();        al.add("java01");        al.add("java02");        al.add("java03");        al.add("java04");        System.out.println("原集合al:"+al);        //在指定的位置添加元素:        al.add(1,"java09");        System.out.println("al.add(1,\"java09\"):"+al);        //删除指定位置元素        al.remove(2);        System.out.println("al.remove(2):"+al);        //修改元素        al.set(1,"java0001");        System.out.println("al.set(1,\"java0001\"):"+al);        //通过角标获取元素        System.out.println("al.get(1):"+al.get(1));        //获取所有元素        //方式1        for(int x = 0;x<al.size();x++)        {            System.out.println(al.get(x));        }        //方式2        System.out.println();        Iterator it = al.iterator();        while(it.hasNext())        {            System.out.println(it.next());        }    }}

输出结果:

原集合al:[java01, java02, java03, java04]al.add(1,"java09"):[java01, java09, java02, java03, java04]al.remove(2):[java01, java09, java03, java04]al.set(1,"java0001"):[java01, java0001, java03, java04]al.get(1):java0001java01java0001java03java04java01java0001java03java04

5、集合框架(ListIterator)

演示代码:

import java.util.*;class ListDemo{    public static void main(String[]args)    {        ArrayList al = new ArrayList();        al.add("java01");        al.add("java02");        al.add("java03");        al.add("java04");        System.out.println("原集合al:"+al);        //通过indexOf获取对象的位置        System.out.println("java02的index是:"+al.indexOf("java02"));        //获取子对象集        List sub = al.subList(1,3);        System.out.println("下标1到2的子对象集是:"+sub);    }}

输出结果:

原集合al:[java01, java02, java03, java04]java02的index是:1下标1到2的子对象集是:[java02, java03]

演示代码:下面这段代码会引起异常,原因是并发操作。

import java.util.*;class ListDemo{    public static void main(String[]args)    {        ArrayList al = new ArrayList();        al.add("java01");        al.add("java02");        al.add("java03");        al.add("java04");        System.out.println("原集合al:"+al);        Iterator it = al.iterator();        //下面代码目的是在迭代过程中,使用集合的方法来对it对象中的元素进行添加或删除元素。        while(it.hasNext())        {            Object obj = it.next();            if(obj.equals("java02"))            {                al.add("java09");//这是集合的方法,会引起并发异常            }            System.out.println("obj"+obj);        }    }}

输出结果:

原集合al:[java01, java02, java03, java04]objjava01objjava02Exception in thread "main" java.util.ConcurrentModificationException    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)    at java.util.ArrayList$Itr.next(ArrayList.java:836)    at day09.ListDemo.main(Outer.java:18)
  • 以上代码引发了问题,就是如何在迭代器中进行元素的添加或删除呢?

    List集合特有的迭代器,ListIterator是Iterator的子接口。在使用Iterator中的迭代器迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常。所以,在迭代,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断、取出和删除的操作。如果想要其他的操作如:添加、修改等,就需要使用其子接口:ListIterator,该接口只能通过ListIterator方法获取

改进代码如下:

import java.util.*;class ListDemo{    public static void main(String[]args)    {        ArrayList al = new ArrayList();        al.add("java01");        al.add("java02");        al.add("java03");        al.add("java04");        System.out.println("原集合al:"+al);        ListIterator li = al.listIterator();        while(li.hasNext())        {            Object obj = li.next();            //添加            if(obj.equals("java02"))            {                li.add("java09");            }            //修改            if(obj.equals("java03"))            {                li.set("java003");            }        }        System.out.println("修改后al:"+al);    }}

输出结果:

原集合al:[java01, java02, java03, java04]修改后al:[java01, java02, java09, java003, java04]

6、集合框架(List集合具体对象的特点)

List

|--ArrayList:底层的数据结构使用的是数组结构,特点:查询快,但增删稍慢,线程不同步。

|--LinkedList:底层使用链表数据结构,增删速度快,查询慢。

|--Vector:底层是数组数据结构,被ArrayList替代了,但它们间不同的是Vector线程同步。

7、集合框架(Vector中的枚举)

import java.util.*;class VectorDemo{    public static void main(String[]args)    {        Vector v = new Vector();        v.add("java01");        v.add("java02");        v.add("java03");        v.add("java04");        Enumeration en = v.elements();        while(en.hasMoreElements())        {            System.out.println(en.nextElement());        }    }}

输出结果:

java01java02java03java04
  • 枚举就是Vector特有的取出方式。

    发现枚举和迭代器很像,其实枚举和迭代是一样的,因为枚举的名称以及方法的名称都过长,所以被迭代器取代了,枚举就很少被人使用了。

8、集合框架(LinkedList)

LinkedList特有方法:

void addFirst(E e);//将指定元素插入此列表的开头。void addLast(E e);// 将指定元素添加到此列表的结尾。boolean offerFirst(E e );//在此列表的开头插入指定的元素。JDK1.6版本boolean offerLast(E e);//在此列表末尾插入指定的元素。JDK1.6版本E getFirst();//返回此列表的第一个元素。E getLast();// 返回此列表的最后一个元素。E peekFirst();//获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。JDK1.6版本E peekLast();//获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。JDK1.6版本E removeFirst();//移除并返回此列表的第一个元素。E removeLast();//移除并返回此列表的最后一个元素。E pollFirst();//获取并移除此列表的第一个元素;如果此列表为空,则返回 null。JDK1.6版本E pollLast();//获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。JDK1.6版本

因为如果集合中没有元素,会出现NoSuchElementException,在JDK1.6出现了替代方法,以上JDK1.6版本的功能,这些方法不会返回异常而是null。

9、集合框架(LinkedList练习)

使用LinkedList模拟一个堆栈或者队列数据结构。 堆栈:先进后出,如同一个杯子。 队列:先进先出,如同一个水管。 测试代码:

import java.util.*;class DuiLie{    private LinkedList link;    DuiLie()    {        link = new LinkedList();    }    public void bianli()    {        for(int x = 0;x<link.size();x++)        {            System.out.print(link.get(x)+" ");        }        System.out.println();    }    public void myAdd(Object obj)    {        link.addFirst(obj);    }    public Object myGet()    {        return link.removeLast();    }    public boolean isNull()    {        return link.isEmpty();    }}class LinkedListTest{    public static void main(String []args)    {        DuiLie dl = new DuiLie();        dl.myAdd("java01");        dl.myAdd("java02");        dl.myAdd("java03");        dl.myAdd("java04");        dl.bianli();//遍历        while(!dl.isNull())        {            System.out.println(dl.myGet());        }    }}

输出结果:

java04 java03 java02 java01 java01java02java03java04

10、集合框架(ArrayList练习)

去除ArrayList集合中的重复元素

import java.util.*;class ArrayListTest{    public static ArrayList SingleElement(ArrayList al)    {        //定义一个临时容器        ArrayList newAl = new ArrayList();        Iterator it = al.iterator();        while(it.hasNext())        {            Object obj = it.next();            if(!newAl.contains(obj))            {                newAl.add(obj);            }        }        return newAl;    }    public static void main(String[]args)    {        ArrayList al = new ArrayList();        al.add("java01");        al.add("java01");        al.add("java02");        al.add("java04");        al.add("java06");        al.add("java01");        System.out.println("原al:"+al);        System.out.println("新al:"+SingleElement(al));    }}

输出结果:

原al:[java01, java01, java02, java04, java06, java01]新al:[java01, java02, java04, java06]

11、集合框架(ArrayList练习)

将自定义对象作为元素存储到ArrayList集合中,并去除重复元素。 比如:存人对象:同姓名同年龄,视为同一个人,为重复元素。 思路: 1、对人描述 2、定义容器,将人存入。 3、取出。

代码:

import java.util.*;class Person{    private String name;    private int age;    Person(String name,int age)    {        this.name = name;        this.age = age;    }    public String getName()    {        return name ;    }    public int getAge()    {        return age;    }    public boolean equals(Object obj)//List集合判断元素是否相同,依据是元素(对象)的equals方法    {        if(!(obj instanceof Person))        {            return false;        }        Person p = (Person)obj;        return this.name.equals(p.name) && this.age == p.age;    }}class ArrayListTest2{    public static ArrayList SingleElement(ArrayList al)    {        //定义一个容器        ArrayList newAl = new ArrayList();        Iterator it = al.iterator();        while(it.hasNext())        {            Object obj = it.next();            if(!(newAl.contains(obj)))//即调用了Person类中的自定义equals函数            {                newAl.add(obj);            }        }        return newAl;    }    public static void main(String []args)    {        ArrayList al = new ArrayList();        al.add(new Person("lisi01",30));        al.add(new Person("lisi02",33));        al.add(new Person("lisi03",22));        al.add(new Person("lisi04",30));        al.add(new Person("lisi01",30));        al = SingleElement(al);        Iterator it = al.iterator();        while(it.hasNext())        {            Person p = (Person)it.next();            System.out.println(p.getName()+"::"+p.getAge());        }    }}

输出结果:

lisi01::30lisi02::33lisi03::22lisi04::30

12、集合框架(HashSet)

Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。 Set

|---HashSet:底层数据结构是哈希表

|---TreeSet

Set集合的功能和Collection是一致的。

测试代码:

import java.util.*;class HashSetDemo{    public static void main(String []args)    {        HashSet hs = new HashSet();        hs.add("java01");        hs.add("java02");        hs.add("java03");        hs.add("java04");        Iterator it = hs.iterator();        while(it.hasNext())        {            System.out.println(it.next());        }//无序存,按哈希表顺序存。    }}

输出结果:

java04java03java02java01

13、集合框架(HashSet存储自定义对象)

往HashSet集合中存入自定义对象,姓名和年龄相同为同一个人,重复元素。

import java.util.*;class HashSetTest{    public static void main(String []args)    {        HashSet hs = new HashSet();        hs.add(new Person("al",11));        hs.add(new Person("a2",12));        hs.add(new Person("a3",13));        hs.add(new Person("a2",12));        Iterator it = hs.iterator();        while(it.hasNext())        {            Person p = (Person)it.next();            System.out.println(p.getName()+"::"+p.getAge());        }    }}class Person{    private String name;    private int age;    Person(String name,int age)    {        this.name = name;        this.age = age;    }    public String getName()    {        return name ;    }    public int getAge()    {        return age;    }    public boolean equals(Object obj)//List集合判断元素是否相同,依据是元素(对象)的equals方法    {        System.out.println("equals() run");        if(!(obj instanceof Person))        {            return false;        }        Person p = (Person)obj;        return this.name.equals(p.name) && this.age == p.age;    }    public int hashCode()    {        System.out.println("hashCode() run");        //字符串类型的变量可以调用字符串自己的哈希值函数,返回字符串自己独有的哈希值        return this.name.hashCode()+this.age*37; //为了保证哈希值唯一而在对象内容不一样的情况下不用去调用equals方法    }}

输出结果:

hashCode() runhashCode() runhashCode() runhashCode() runequals() runal::11a3::13a2::12

HashSet是如何保证元素唯一性的呢?

是通过元素(对象)的两个方法:hashCode和equals来完成,如果元素的hashCode值相同,才会判断equals是否为true,如果元素的hashCode值不同,不会调用equals。

14、集合框架(HashSet判断和删除的依据)

import java.util.*;class HashSetTest{    public static void main(String []args)    {        HashSet hs = new HashSet();        Person p1 = new Person("a2",12);        hs.add(new Person("al",11));        hs.add(p1);        hs.add(new Person("a3",13));        System.out.println("....");        //hs.add(new Person("a2",12));        System.out.println("测试判断是否包含的功能:"+hs.contains(new Person("a2",12)));        hs.remove(p1);        /*        Iterator it = hs.iterator();        while(it.hasNext())        {            Person p = (Person)it.next();            System.out.println(p.getName()+"::"+p.getAge());        }        */    }}class Person{    private String name;    private int age;    Person(String name,int age)    {        this.name = name;        this.age = age;    }    public String getName()    {        return name ;    }    public int getAge()    {        return age;    }    public boolean equals(Object obj)//List集合判断元素是否相同,依据是元素(对象)的equals方法    {        System.out.println("equals() run");        if(!(obj instanceof Person))        {            return false;        }        Person p = (Person)obj;        return this.name.equals(p.name) && this.age == p.age;    }    public int hashCode()    {        System.out.println("hashCode() run");        //字符串类型的变量可以调用字符串自己的哈希值函数,返回字符串自己独有的哈希值        return this.name.hashCode()+this.age*37; //为了保证哈希值唯一而在对象内容不一样的情况下不用去调用equals方法    }}

输出结果:

hashCode() runhashCode() runhashCode() run....hashCode() runequals() run测试判断是否包含的功能:truehashCode() run

对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。

0 0
原创粉丝点击