day14集合类,迭代器。List,列表迭代器,vector,LinkedList。Set,HashSet

来源:互联网 发布:l800清零软件中文 编辑:程序博客网 时间:2024/05/16 02:19
/*集合类,迭代器。List,列表迭代器,vector,LinkedList。Set,HashSet*//*集合类:为什么出现集合类?面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。数组和集合类同是容器,有何不同?数组虽然也可以存储对象,但长度是固定的,集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象。集合类的特点集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。集合框架:先看顶层,所有的共性。                  (接口)collectionList                         SetArrayList    linkedList Vector        HashSet   TreeSet为什么会出现这么多容器?因为每个容器对数据的存储方式都有不同。这个存储方式称之为:数据结构。*//*add方法的参数类型是Object,以便于接收任意类型对象集合中不可能存放对象实体,都是对象的引用(地址).什么是迭代器呢?其实就是集合的取出元素的方式。把取出方式定义在集合的内部,内部类。这样取出方式就可以直接访问集合内的元素那么取出方式就被定义成了内部类而每一个容器的数据结构不同所以取出的动作细节也不一样。但是都有共性内容判断和取出,那么可以将共性抽取。那么这些内部类都符合一个规则,该规则是Iterator如何获取集合的取出对象呢?通过一个对外提供的方法:iterator();*/class  CollectionDemo{public static void main(String[] args) {method_get();}public static void method_get(){List al = new ArrayList();al.add("java01");al.add("java02");al.add("java03");al.add("java04");//获取迭代器,用于取出集合中的元素。Iterator it = al.iterator();while(it.hasNext())//for循环可以更省内存{sop(it.next());}}public static void method_2(){ArrayList al1 = new ArrayList();al1.add("java01");al1.add("java02");al1.add("java03");al1.add("java04");ArrayList al2 = new ArrayList();al2.add("java01");al2.add("java02");al2.add("java05");al2.add("java06");al1.retainAll(al2);//取交集,al1中只会保留和al2中相同的元素//al1.removeAll(al2);去掉一堆相同的元素sop("al1:"+al1);sop("al2:"+al2);}public static void base_method(){ //创建一个集合容器,使用Collection接口的子类,ArrayListArrayList al = new ArrayList();//加元素al.add("java01");//add(Object obj)任意类型的对象al.add("java02");al.add("java03");al.add("java04");//打印原集合sop("old"+al);//3删除元素//al.remove("java02");//al.clear();//清空集合//判断元素sop("java03是否存在:"+al.contains("java03"));sop("集合是否为空"+al.isEmpty());//2获取个数,集合长度sop("size:"+al.size());//打印改变后的集合sop(al);}public static void sop(Object obj){System.out.println(obj);}}/*CollectionList:元素是有序的,元素可以重复。因为该集合体系有索引|--Arraylist:底层的数据结构使用数组结构。特点:读(查询)(修改)快,改(增删)慢。一个改动,所有的编号都要动。线程不同步。默认长度为10,超出时,50%延长空间|--LinkedList:底层使用链表数据结构。查询慢,改(增删)快。|--Vector:底层是数组数据结构,1.2以后才出现其他的集合框架。Vector是线程同步的。被ArrayList替代了。默认长度为10,超出时100%延长空间Set:元素是无序的,元素不可重复。List集合:特有方法。凡是可以操作角标的方法都是该体系特有的方法使用Iterator可以迭代元素,但是在迭代过程中不允许进行增删操作。ListIterator可以在迭代过程中对元素进行修改操作。在ListIterator中提供了比Iterator更多的操作方法,如add和set方法,从后向前遍历,其余的跟Iterator没什么区别.增add(int index, E element) 在列表的指定位置插入指定元素(可选操作)。addAll(int index, Collection<? extends E> c) 将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。删remove(index);改set(index,element)查get(index);subList(from,to);listIterator();List集合特有的迭代器。ListIterator是Iterator的子接口在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发操作异常,所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的只能对元素进行判断,取出,删除操作。如果想要其他操作如添加,修改等,就要使用其子接口。ListIterator。逆向遍历:hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。sop(al);ListIterator li = al.listIterator();while(li.hasNext()){Object obj = li.next();if(obj.equals("java02"))li.remove();//add(),set().sop("obj="+obj);//这个为什么移除了还打印所有?li.next(),object指向java02,remove移除了元素在集合中的引用,元素还在内存当中。元素还被object使用,所以被打印。}sop("al="+al);打印结果:0102030102030103*/import java.util.*;class  ListDemo{//listIterator()           //返回此列表元素的列表迭代器(按适当顺序)。public static void main(String[] args) {ArrayList al = new ArrayList();//添加元素al.add("java01");al.add("java02");al.add("java03");ListIterator li = al.listIterator();while(li.hasNext()){Object obj = li.next();if(obj.equals("java02"))//li.add("java009");li.set("java0006");}sop("al="+al);/*//在迭代过程中,准备添加或者删除元素Iterator it = al.iterator();while(it.hasNext()){Object obj = it.next();if(obj.equals("java02"))//al.add("java008");//会出现并发操作异常,在迭代器操作时,不可以用集合方法同时操作。//it.remove();//迭代器方法,将java02在集合中移除sop("obj="+obj);}*/}public static void listDemo() {ArrayList al = new ArrayList();//添加元素al.add("java01");al.add("java02");al.add("java03");sop("原集合是:"+al);//在指定位置添加元素al.add(1,"java09");//删除指定位置的元素//al.remove(2);//修改元素//al.set(2,"java007");//通过角标获取元素//sop("get(1)"+al.get(1));//sop(al);//get()获取所有元素for(int x = 0;x<al.size();x++){//System.out.println("al("+x+")="+al.get(x));}Iterator it = al.iterator();while(it.hasNext()){sop("next:"+it.next());}sop("index="+al.indexof("java02"));//获取位置List sub = al.subList(1,3);//子集合sop("sub="+sub);}public static void sop(Object obj){System.out.println(obj);}}/*vector:elements()   返回此向量的组件的枚举。枚举就是Vector特有的取出方式。发现枚举和迭代器很像。其实枚举和迭代是一样的。为什么要出迭代?因为枚举的名称以及方法的名称都过长。所以被迭代器取代了。*/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());//迭代,记住这种写法,合并流要用到枚举。}}}/*LinkedList特有方法addFirst();将指定元素插入此列表的开头。addLast();将指定元素添加到此列表的结尾。getFirst(); 返回此列表的第一个元素。getLast(); 返回此列表的最后一个元素。获取元素,但不删除元素。removeFirst(); 移除并返回此列表的第一个元素。removeLast();移除并返回此列表的最后一个元素。获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementsException因为会有异常,所以1.6版本后出现如下替代方法。获取元素,但是元素被删除。如果集合中没有元素,返回null.offerFirst(E e)   在此列表的开头插入指定的元素。offerLast(E e)   在此列表末尾插入指定的元素。peek()   获取但不移除此列表的头(第一个元素)。peekFirst()   获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。peekLast()   获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。pollFirst()  获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 pollLast()  获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。*/class LinkedListDemo {public static void main(String[] args) {LinkedList link = new LinkedList();link.addFirst("java01");link.addFirst("java02");link.addFirst("java03");link.addFirst("java04");sop(link);//取出元素另一种方法while(!link.isEmpty()){sop(link.removeFirst());}}public static void sop(Object obj){System.out.println(obj);}}/*LinkedList模拟一个堆栈或者队列数据结构堆栈:先进后出,如同一个杯子队列:先进先出,如同一个水管*/import java.util.*;class DuiLie{private LinkedList link;DuiLie(){link = new LinkedList();}public void myAdd(Object obj){link.addFirst(obj);//向第一个位置添加}public Object myGet(){ return link.removeFirst();}public boolean isNull()//其实都是把LinkedList方法封装。{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");while(!dl.isNull())System.out.println(dl.myGet());}}//二个ArrayList练习。/*去除arraylist中的重复元素思路:定义一个新的容器,向容器中添加元素,添加之前先判断里面有没有要添加的元素。*/import java.util.*;class ArrayListTest {public static void main(String[] args) {ArrayList al = new ArrayList();al.add("java01");al.add("java02");al.add("java01");al.add("java02");al.add("java01");al.add("java03");al.add("java01");al.add("java03");/*在迭代时循环中next调用一次,就要hasNext判断一次,指针向下走一次。Iterator it = al.iterator();while(it.hasNext()){sop(it.next()+"..."+it.next());//不可取的写法。}*/sop(al);al = singleElement(al);sop(al);}//包装成方法。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 sop(Object obj){System.out.println(obj);}}/*将自定义对象作为元素存到ArrayList集合中,并去除重复元素。比如:存人对象,同姓名年龄,视为同一个人,为重复元素。。思路:1对人描述,将数据封装进入对象Person2定义容器,将人存入3取出。List集合判断元素是否相同,依据就是元素的equals方法,无论是包含,还是删除。*/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)//复写{if(!(obj instanceof Person))return false;//先判断是否包含,更严谨的话,这里直接抛异常。我不传person,传DEMO,没意义Person p = (Person)(obj);return this.name.equals(p.name) && this.age==p.age;}}class  ArrayListTest2{public static void main(String[] args) {ArrayList al = new ArrayList();al.add(new Person("lisi01",30));al.add(new Person("lisi02",32));al.add(new Person("lisi02",32));al.add(new Person("lisi03",33));al.add(new Person("lisi03",33));al.add(new Person("lisi04",35));al = singleElement(al);//为什么这里调用了比较方法,可以还是加入了相同的呢?//因为此处调用了object的equals方法,而我们是new的对象,地址是不同的。//应该重写自己的equals方法。判断方法不同,ArrayList只判断对象是否相同。Iterator it = al.iterator();while(it.hasNext()){//sop(it.next().getName());//这里是不行的,al.add(Object obj),it.next()是Object,//而object里面没有getName方法,必须转换成Person。Person p = (Person)(it.next());//Object转换成了Person,所以就有了getName方法sop(p.getName()+"::"+p.getAge());}}public static void sop(Object obj){System.out.println(obj);}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;}}/*|--Set:元素是无序的(存入和取出的顺序不一定一致),元素不可重复。|--HashSet:底层数据结构是哈希表。线程是非同步的。是如何保证元素的唯一性的呢?(依据)判断是通过元素的两个方法,hashCode和equals来完成。如果元素HashCode一样,才会再去判断equals是否为真。如果元素的HashCode不同,不会去调用equals().注意,对于判断元素是否存在,以及删除等操作,依赖hashCode和equals方法来完成|--TreeSet:Set集合的功能和Collect是一致的,哈希表存对象。-HashSet先比较哈希值,如果相同,再比较对象equals()。*/import java.util.*;class HashSetDemo{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args) {HashSet hs = new HashSet();sop(hs.add("java01"));sop(hs.add("java01"));//HashSet返回的是boolean,无序的,先看有没有。hs.add("java02");hs.add("java03");hs.add("java04");Iterator it = hs.iterator();while(it.hasNext()){sop(it.next());}}}import java.util.*;/*往hashSet集合中存入自定义对象姓名和年龄相同为同一个人,重复元素。*/class  HashSetTest{public static void main(String[] args) {HashSet hs = new HashSet();hs.add(new Person("a1",11));hs.add(new Person("a2",12));hs.add(new Person("a3",13));hs.add(new Person("a3",13));//hs.add(new Demo());//hs.add(new Person("a2",12));//hs.add(new Person("a2",12));//hs.add(new Person("a2",12));Iterator it = hs.iterator();while(it.hasNext()){Person p = (Person)it.next();sop(p.getName()+"..."+p.getAge());}}public static void sop(Object obj){System.out.println(obj);}}class Demo{}class Person{private String name;private int age;Person(String name,int age){this.name = name;this.age = age;}public int hashCode(){//System.out.println(this.name+"...hash");//return 60;//如果哈希地址一样,再调用equals。return name.hashCode()+age*39;//*39,这是为了尽量保证唯一。}public  String getName(){return name;}public  int getAge(){return age;}public boolean equals(Object obj)//注意复写一定是object参数{if(!(obj instanceof Person))return false;//先判断是否包含,更严谨的话,这里直接抛异常。我不传person,传DEMO,没意义Person p = (Person)(obj);System.out.println(this.name+"..."+p.name);//如果此处没有打印,没有调用,//因为地址不同,不再比较equalsreturn this.name.equals(p.name) && this.age==p.age;}}