java基础学习(十)容器-1

来源:互联网 发布:php中sleep函数 编辑:程序博客网 时间:2024/05/29 18:58

java容器类库的用途是保存对象,它提供两种不同的类型:
1、Collection。独立元素的序列。子类List必须按照插入的顺序保存元素;Set不能有重复的元素。
2、Map。一组成对的键值对对象。

在创建具体类的对象时,将其转型为对应的接口,然后在其余的代码中都使用这个接口,例如:

List<String> strList=new ArrayList<>();List<String> strList2=new LinkedList<>();

但是LinkList具有在List中未包含的额外方法,如果想使用这些额外方法,那就不能将它们向上转型为更通用的接口。

实例,在Collection中填充Integer对象:

public static void main(String[] args) {        //继承自Collection的类的对象都可以使用        Collection<Integer> c=new ArrayList<Integer>();        for(int i=0;i<10;i++){            //在使用任何种类的List,不关心是否存在重复元素            //而在Set中,只有元素不存在才会被添加            c.add(i);        }        //遍历容器        for(Integer i:c){            System.out.println(i);        }    }

利用Arrays和Collection类中的实用方法,添加一组元素:

public static void main(String[] args) {        //Arrays.asList()方法可以接受一个数组或者一个逗号分隔的元素列表(可变参数,元素个数不固定)        Collection<Integer> collection=new ArrayList<Integer>(Arrays.asList(1,2,3));        Integer[] moreInt=new Integer[]{5,6,7};        //利用addAll()添加元素,只能接受另一个Collection类型        collection.addAll(Arrays.asList(moreInt));        for(Integer i:collection){            System.out.print(i+" ");        }        //注意,上面的collection只能接受Collection对象,这样不灵活        //可以使用Collections.addAll()方法,可以接受Collection对象,        //以及使用一个数组  或者  用逗号分隔的元素列表(可变参数)        //但是不能三者都放在一起,且必须有一个Collection对象,因为要将元素填充到collection中        Collections.addAll(collection,9,8);        Collections.addAll(collection,moreInt);        System.out.println();        for(Integer j:collection){            System.out.print(j+" ");        }    }//结果:1 2 3 5 6 7 1 2 3 5 6 7 9 8 5 6 7 

当直接使用Arrays.asList()的输出,将其作为一个List,其底层表示的是数组,不能改变数组大小。

public static void main(String[] args) {        List<Integer> intList= Arrays.asList(3,2,4);        //增加或删除元素,会导致出现异常:UnsupportedOperationException        //intList.add(6);        //intList.add(4,6);        //intList.remove(0);        for(Integer i:intList){            System.out.println(i+" ");        }    }

Arrays.asList()方法会根据元素的实际类型产生正确的List类型:

public class AsListInference {    public static void main(String[] args) {        List<Snow> sonw= Arrays.asList(new Power(),new Crusty(),new Slush());        //不能编译通过        //List<Snow> snows_1=Arrays.asList(new Light(),new Heavy());        //混合情况也不能编译        //List<Snow> snow_2=Arrays.asList(new Power(),new Light());        //正确的方法,创建一个空的collection对象,在进行填充        List<Snow> snows_3=new ArrayList<Snow>();        Collections.addAll(snows_3,new Light(),new Heavy());        //也可以使用显式类型参数说明,告诉编译器List的实际类型,        List<Snow> snows_4=Arrays.<Snow>asList(new Light(),new Heavy());    }}class Snow{}class Power extends Snow{}class Light extends Power{}class Heavy extends Power{}class Crusty extends Snow{}class Slush extends Snow{}

打印数组中的元素可以使用Array.toString()方法,但是容器可以直接打印:

public class PrintContain {    static Collection fill(Collection<String> collection){        collection.add("rat");        collection.add("cat");        collection.add("dog");        collection.add("dog");        return collection;    }    public static void main(String[] args) {        //打印数组        String[] str=new String[]{"rat","cat","dog","dog"};        System.out.println(Arrays.toString(str));        //打印容器        System.out.println(fill(new ArrayList<String>()));        System.out.println(fill(new LinkedList<String>()));        System.out.println(fill(new HashSet<String>()));        System.out.println(fill(new TreeSet<String>()));        System.out.println(fill(new LinkedHashSet<String>()));    }}//结果//打印数组[rat, cat, dog, dog]//List类型按照插入的顺序保存元素[rat, cat, dog, dog][rat, cat, dog, dog]//Set类型,每个相同的项保存一次//HashSet能最快获取元素,存储顺序无意义[rat, cat, dog]//TreeSet按照比较结果升序保存对象[cat, dog, rat]//LinkedHashSet按照被添加的顺序保存对象[rat, cat, dog]

List容器
List可以将元素维护在特定的序列中,可以在List的中间插入和移除元素。
两种类型的List:
1、ArrayList:擅长随机访问元素,但在其中插入和移除元素时较慢
2、LinkedList:方便在List中间进行插入和删除操作,在随机访问方面比较慢。

迭代器
迭代器是一个轻量级对象,主要是遍历并选择序列中的对象,而不必关系该序列底层的结构。Java中的Iterator只能单向移动(也就是只能next,向前移动)。

public static void main(String[] args) {        List<String> strList=new ArrayList<String>();        Collections.addAll(strList,"dog","cat","mouse","rate");        //不必关心容器的确切类型        //方法iterator()返回一个Iterator,将返回序列的第一个元素        Iterator<String> iterator=strList.iterator();        //hasNext()检查序列中是否还有元素        while(iterator.hasNext()){            //获取序列中的下一个元素            String str=iterator.next();            System.out.print(str+" ");        }        System.out.println();        //因为iterator已经到最后没有元素了,需要重新建立对象        iterator=strList.iterator();        for(int i=0;i<2;i++){            //将新近返回的元素删除            iterator.next();            iterator.remove();        }        System.out.print(strList);    }结果:dog cat mouse rate [mouse, rate]

ListIterator
它是Iterator的子类型,只能用于各种List类的访问。并且可以双向移动。

public static void main(String[] args) {        List<String> petList=new ArrayList<String>();        Collections.addAll(petList,"dog","cat","pig","rate");        ListIterator<String> li=petList.listIterator();        while (li.hasNext()){            //返回迭代器在列表中指向的当前位置的前一个和后一个元素的索引           String ne= li.next();           int next= li.nextIndex();           int pre= li.previousIndex();            System.out.print(ne+" "+next+" "+pre+" ");        }        System.out.println();        //也可以反向移动        while (li.hasPrevious()){           String previous= li.previous();            System.out.print(previous+" ");        }        System.out.println();        //可以一开始就指向列表索引为2的元素处的ListIterator        li=petList.listIterator(2);        while (li.hasNext()){            System.out.print(li.next()+" ");        }    }//结果:dog 1 0 cat 2 1 pig 3 2 rate 4 3 rate pig cat dog pig rate 

LinkedList
在List中插入和移除操作的效率比ArrayList更高效。但在随机访问方面要逊色一些。

public static void main(String[] args) {        List<String> link=new LinkedList<String>();        Collections.addAll(link,"dog","rat","mutt","pugl");        System.out.println("link="+link);        //返回列表的第一个元素        //list中没有addFirst()方法        System.out.println("link.get()="+link.get(0));        //移除并返回元素        System.out.println("link.remove()="+link.remove(1));    }//结果link=[dog, rat, mutt, pugl]link.get()=doglink.remove()=rat

Stack
栈指后进先出的容器,最后压入栈的元素,最后弹出栈。
LinkedList能够直接实现栈的所有功能的方法,因此可以直接将LinkedList作为栈使用。

public class StackTest<T> {    //Stack是用LinkedList实现的    private LinkedList<T> storge=new LinkedList<T>();    //插入一个元素    public void push(T t){storge.addFirst(t);}    //返回栈顶元素,但是并不移除    public T peek(){return storge.getFirst();}    //返回并移除栈顶元素    public T pop(){return storge.removeFirst();}    //判断栈是否为空    public boolean empty(){return storge.isEmpty();} }

Set
set不保存重复对象。
存储方式的不同:HashSet使用的散列函数,输出的元素没有规律。
TreeSet将元素存储在红-黑树数据结构,对结果进行排序。
LinkedHashSet也使用散列函数,但是使用了链表来维护元素的插入顺序。

HashSet 和TreeSet

public static void main(String[] args) {        Random random=new Random(100);        Set<Integer> intset=new HashSet<Integer>();        Set<Integer> treeSet=new TreeSet<Integer>();        Collections.addAll(intset,21,32,4,6,1);        Collections.addAll(treeSet,21,32,4,6,1);        Iterator<Integer> it=intset.iterator();        while(it.hasNext()){            //遍历HashSet,输出的顺序没有规律可循            System.out.print(it.next()+" ");        }        System.out.println();        Iterator<Integer> itTree=treeSet.iterator();        while(itTree.hasNext()){            //遍历TreeSet,对结果进行排序            System.out.print(itTree.next()+" ");        }    }  //结果  32 1 4 21 6   1 4 6 21 32 

Map

public static void main(String[] args) {        Map<String,String> petMap=new HashMap<String, String>();        petMap.put("my Cat","Molly");        petMap.put("my dog","ginger");        petMap.put("MY Mamster","Bosco");        //map中包含某个键或值        petMap.containsKey("my dog");        petMap.containsValue("my Cat");        //遍历map        //keySet返回键的Set        for(String my:petMap.keySet()){            System.out.println("主人:"+my+"宠物:"+petMap.get(my));        }        //values返回值的collection        Iterator<String> valIte=petMap.values().iterator();        while(valIte.hasNext()){            System.out.println(valIte.next());        }    }

Queue
队列是典型的先进先出的容器。从容器的一端放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。队列可以安全的将对象从一个任务传输给另一个任务。
LinkedList实现了Queue接口,可以把它作为一种实现。

public static void main(String[] args) {        Queue<Integer> queue=new LinkedList<Integer>();        Random random=new Random(47);        //offer方法将一个元素插入到队尾,返回true        System.out.println(queue.offer(444));        for(int i=0;i<10;i++){            queue.offer(random.nextInt(i+10));        }        System.out.println(queue);    }

Collection和Iterator
Collection是描述所有序列容器的共性的根接口,它会被认为是一个附属接口,为了表示其他接口的共性而出现的接口。AbstractCollection提供Collection的默认实现,在穿件AbstractCollection的子类型时,而其中没有不必要的代码的重复。

迭代器和容器都可以用在Map或Collection的子类型来工作。

//使用迭代器    public static void display(Iterator<String> it){        while (it.hasNext()){            System.out.print(it.next()+"  ");        }    }    //使用容器    public static void display(Collection<String> c){        for(String str:c){            System.out.println(str+" ");        }    }    public static void main(String[] args) {        List<String> strList=new ArrayList<String>();        Set<String> strSet=new HashSet<String>();        Collections.addAll(strList,"dog","pig","cat");        Collections.addAll(strSet,"first","second","third");        Map<String,String> strMap=new LinkedHashMap<String, String>();        strMap.put("zhangsan","lisi");        strMap.put("wangwu","zhaoliu");        //使用迭代器        display(strList.iterator());        display(strSet.iterator());        display(strMap.keySet().iterator());        //使用容器        display(strList);        display(strSet);        display(strMap.values());    }

当要实现一个不是Collection的外部类时,让其实现该接口会非常困难,即使通过继承AbstractCollection而很容易实现,但是还是需要强制实现iterator()和size()方法。此时使用迭代器比较方便。

Foreach与迭代器
foreach语法主要用于数组,但是也可以应用于任何Collection对象。所有的Collection类(不包括各种Map)都是Iterable类型,数组也不是Iterable类型。Iterable接口包含一个能够产生Iterator的iterator()方法。并且Iterable接口被foreach用来在序列中移动。
任何实现了Iterable的类,都可以将它应用于foreach中。

public static void main(String[] args) {        Map<String,String> strMap=new HashMap<String, String>();        strMap.put("one","zhangsan");        strMap.put("two","lisi");        strMap.put("three","wangwu");        for(Map.Entry entry:strMap.entrySet()){            System.out.println(entry.getKey()+":"+entry.getValue());        }    }//结果one:zhangsantwo:lisithree:wangwu
0 0
原创粉丝点击