Java容器(集合),持有对象总结

来源:互联网 发布:淘宝能卖军用品吗 编辑:程序博客网 时间:2024/05/21 19:50

基本概念

如下图:

为解决数组固定尺寸的限制,java类库提供容器类来解决这问题。其中包括List,Set,Map,Queue,也称集合类。编程时可以将任意数量的对象置于容器,不用在意容器大小。
容器类库可以划分为:

  • Collection:独立的序列,元素服从一条或多条规则。其中List按照插入的顺序保持元素,Set不能有重复元素,Queue按照排队规则确定对象产生的顺序。
  • Map:一组成对的键值对对象,允许用键查找,ArrayList允许用数字查找值。

向Collection添加一组元素

java.util包中的Arrays和Collections类的Arrays.asList()方法和Collections.addAll()方法可以在Collection对象中添加一组元素。

  • Arrays.asList()接受一个数组或是逗号分隔的元素列表,将其妆化为List对象;
  • Collections.addALl()接受一个Collection对象,以及一个数组或者逗号分隔的元素列表,将元素添加到Collection中;
  • Collection.addAll()运行快,只能接受Collection对象作为参数,所以不如前两者灵活。

如下:

public class addGroups(){    public static void main(String[] args){        Conllection<Integer> conllection = new ArrayList<Integer>(Arrays.asList(1,2,3));        Integer[] moreInts = {4,5,6};        collection.addAll(Arrays.asList(moreInts));        Collections.addAlls(conllection, 7,8,9);        Collections.addAlls(conllection, moreInts);    }}

可以直接使用Arrays.asList()的输出,将其作为List,此时,底层表示为数组,无法调整尺寸,若用add(),delete()添加或删除元素,会引发改变数组尺寸,产生错误。

List<Integer> list = Arrays.asList(10,11,12);list.set(1,99); //可以修改元素值list.add(13); //产生错误,尝试改变数组尺寸

List

List可以将元素维护在特定的序列中,有两种类型List:

  • ArrayList:随机访问元素快速,在List中插入和移除元素比较慢
  • LinkedList:通过代价较低的在List中进行插入删除,提供了优化的顺序访问,LinkedList在随机访问方面比较慢,但特性集比ArrayList更大。

具体方法操作如下例所示:

import java.util.*;import static java.lang.System.out;public class Main {     public static void main(String[] args) {        List<String> list = new ArrayList<String>(Arrays.asList("red","blue","white","grey"));        //add(int index,String value)向List中添加插入元素        list.add("yellow");        out.println(list);        //contains(String value)判断List中是否包含该元素        out.println(list.contains("yellow"));        //indexOf(String value)查询元素的位置        out.println(list.indexOf("blue"));        //remove(String value)删除元素        out.println(list.remove("blue"));        out.println(list);        //subList(int index,int _index)截取片断,返回一个新的List对象        List<String> _list = list.subList(1,4);        out.println(_list);        //containAll(List object)判断一个List中是否包含另一个List中的所有值        out.println(list.containsAll(_list));        //Collections.sort(List object)对List进行排序        Collections.sort(_list);        out.println(_list);        List<String> copy_list = new ArrayList<>(list);        _list = Arrays.asList(list.get(1),list.get(3));        out.println(_list);        out.println(copy_list);        //retainAll()取交集        copy_list.retainAll(_list);        out.println(copy_list);        //removeALl()从List中移除参数List中所有元素        copy_list.removeAll(_list);        out.println(copy_list);        //set()设值,在指定索引处,替换位置上的元素        list.set(1,"green");        out.println(list);        //addAll()在List中插入新的列表        list.addAll(1,_list);        out.println(list);        //isEmpty()判断List是否为空        out.println(list.isEmpty());        //clear()清除所有元素        list.clear();        out.println(list);        //toArray()将Collection转换为一个数组,为重载方法,无参版本返回的是Object数组        Object[] array = _list.toArray();        out.println(array[0]);    }}

Iterator

迭代器(设计模式)是一个对象,用来遍历并选择序列中的对象,通常被称为轻量级对象,创建代价小。Java的Iterator只能单向移动。

  • iterator()要求容器返回一个Iterator;
  • 使用next()获得序列中下一个元素;
  • 使用hasNext()检查序列中是否还有元素;
  • remove()将迭代器返回的元素删除;

如下示例:

import java.util.*;import static java.lang.System.out;public class Main {    public static void main(String[] args) {        List<String> list = new ArrayList<String>(Arrays.asList("red","blue","white","grey"));        Iterator<String> iter = list.iterator();        while(iter.hasNext()){            String s = iter.next();            out.println(s);        }        for(String _s : list)            out.println(_s);        iter = list.iterator();        for(int i = 0;i < 2;i++){            iter.next();            iter.remove();        }        out.println(list);    }}

若是所创建的List能把相同的代码应用于Set,将显得很方便,代码重组显然不适合,所以我们使用迭代器。创建一个display()方法:

import java.util.*;import static java.lang.System.out;public class Main {    public static void display(Iterator<String> iter){        while(iter.hasNext()){            String s = iter.next();            out.println(s);        }    }    public static void main(String[] args) {        List<String> list = new ArrayList<String>(Arrays.asList("red", "blue", "white", "grey"));        LinkedList<String> L_list = new LinkedList<String>(list);        HashSet<String> H_list = new HashSet<String>(list);        TreeSet<String> T_list = new TreeSet<String>(list);        display(list.iterator());        display(L_list.iterator());        display(H_list.iterator());        display(T_list.iterator());    }}

ListIterator

ListIterator是Iterator的子类型,用于LIst的访问。Iterator只能单向移动,但是ListIterator可以双向移动。
其中的previousIndex()和nextIndex()可以获取到当前位置的前一个和后一个元素索引,hasPrevious()判断一个元素是否存在,set()用于替换元素。

import java.util.*;import static java.lang.System.out;public class Main {    public static void main(String[] args) {        List<String> list = new ArrayList<String>(Arrays.asList("red", "blue", "white", "grey"));        ListIterator<String> iter = list.listIterator();        while(iter.hasNext()){            System.out.print(iter.next()+","+iter.nextIndex()+","+iter.previousIndex()+" ");        }        System.out.println();        while(iter.hasPrevious())            out.print(iter.previous()+" ");        out.println();        iter = list.listIterator(2);        while(iter.hasNext()){            iter.next();            iter.set("girl");        }        out.println(list);    }}

LinkedList

LinkedList随机访问比ArrayList逊色,但是元素的插入删除比ArrayList迅速的多。LinkedList添加了栈,队列,双端队列的方法。

  • getFirst(),element():返回列表的头元素,而不是移除,若列表为空,则抛出NoSunchElementException;
  • peek():同上,只是列表为空时,返回null;
  • removeFirst(),remove():移除并返回列表的头,列表为空抛出NoSunchElementException;
  • poll():同上,只是列表为空返回null;
  • addFirst(),add(),addLast():将某个元素插入到列表的(端)尾部;
  • removeLast():移除并返回列表最后一个元素;

    import java.util.*;
    import static java.lang.System.out;
    public class Main {
    public static void main(String[] args) {
    LinkedList list = new LinkedList(Arrays.asList(“red”,”blue”,”green”,”yellow”));
    out.println(list);
    out.println(“getFirst():”+list.getFirst());
    out.println(“element():”+list.element());
    out.println(“peek():”+list.peek());
    out.println(“remove():”+list.remove());
    out.println(“removeFirst():”+list.removeFirst());
    out.println(“poll():”+list.poll());
    list.addFirst(“red”);
    list.addLast(“blue”);
    out.println(list);
    out.println(“removeLast():”+list.removeLast());
    }
    }

    [red, blue, green, yellow]
    getFirst():red
    element():red
    peek():red
    remove():red
    removeFirst():blue
    poll():green
    [red, yellow, blue]
    removeLast():blue

Stack

“栈”称为“先进后出”(LIFO)容器。有时也称作叠加栈。最后压入的元素,最后一个弹出。LinkedList可以实现Java中的栈。
使用LInkedList定义一个Stack类:

import java.util.LinkedList;public class Stack<T>{    private LinkedList<T> Storage = new LinkedList<T>();    public void push(T v) {        storage.addFirst(v);    }    public T peek(){        return storage.getFirst();    }    public T pop(){        return storage.removeFirst();    }    public boolean empty(){        return storage.isEmpty();    }    public String toString(){        return storage.toString();    }}

Set

Set不保存重复元素,常用作测试归属性可以很容易判断对象是否在Set中,加快了对快速查询的优化。
Set有着与Collection完全一样的接口,没有任何额外功能,只是行为不同而已。如下为Set示例:

import java.util.*;import static java.lang.System.out;public class Main {    public static void main(String[] args) {        Random rand = new Random(47);        //Set<Integer> set = new HashSet<Integer>();        //Set<Integer> set = new TreeSet<Integer>();        Set<Integer> set = new LinkedHashSet<Integer>();        for(int i = 0;i<1000;i++){            set.add(rand.nextInt(30));        }        out.println(set);    }}

运行结果:

HashSet:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]TreeSet:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]LinkedHashSet[8, 5, 13, 11, 1, 29, 28, 20, 12, 7, 18, 21, 19, 16, 0, 14, 3, 26, 25, 10, 2, 24, 4, 6, 22, 27, 17, 9, 23, 15]

由运行结果可知,HashSet和TreeSet按顺序输出,以往的HashSet使用的是散列,现在或许已经改变了元素存储方式,TreeSet存储在红黑树中,LinkedHashSet使用了散列存储,看起来更是使用了链表维护元素插入顺序。

  • contains()和containsAll(Set对象)用来检查元素的归属
  • remove()和removeAll(Set对象)用来删除元素

若是想要列出一个文件上所有的单词时,可以使用net.mindview.TextFile工具,并将其写入Set中。

new TextFile("Exzample.hava", "\\W+");

其中“\W+”表示正则表达式“一个或多个字母”。

Queue

队列是“先进先出”容器,容器一段放入元素,另一端取出。LinkedList支持队列的行为,实现了Queue接口,可以通过LinkedList向上转型为Queue。

Queue<String> queue = new LinkedList<String>();

其中Queue的offer()方法可以将一个元素插入到队尾,或返回false。peek()和element()在不移除的情况返回队头。poll()和remove()移除并返回队头。

Map

Map是一种将对象与对象相关联的设计,HashMap设计用来快速访问,而TreeMap保持“键”始终处于排序状态,所以没有HashMap快,LInkedHashMap保持元素插入的顺序,但也通过散列提供快速访问的能力。
Map可以将对象映射到其他对象。例如,对Random产生的数字进行计数,键位Random产生的数字,值是数字出现的次数。

import java.util.*;import static java.lang.System.out;public class Main {    public static void main(String[] args) {        Random rand = new Random(47);        Map<Integer, Integer> map = new HashMap<Integer, Integer>();        for(int i =0; i<1000;i++){            int r= rand.nextInt(30);            Integer num = map.get(r);            map.put(r, num==null?1:num+1);        }        out.println(map);    }}

此外,可以通过containsKey()和containsValue()测试一个Map,判断是否包含某个键或某个值。

import java.util.*;import static java.lang.System.out;public class Main {    public static void main(String[] args) {        Map<Integer, String> map = new HashMap<Integer, String>();        map.put(0, "red");        map.put(1, "blue");        map.put(2, "yellow");        out.println(map);        out.println(map.containsKey(1));        out.println(map.containsValue("blue"));    }}
原创粉丝点击