java 容器

容器

容器基本类型: List, Set, Queue, Map

 

  • 泛型和类型安全的容器

class Fuji extends Apple {}

ArrayList<Apple> apples = new ArrayList<Apple>();

apples.add(new Fuji());  >>> 可以添加泛型的子类

for (Apple c : apples){   >>> foreach 来遍历所有元素

System.out.println(c);

 

 

二.基本概念, 容器类类库的用途是:保存对象.

(一)Collection,一个独立元素的序列,这些元素都服从一条或多条规则.

         所有的Collection都可以用foreach语法遍历.

List必须按照插入的顺序保存元素.

Set不能有重复元素

Queue按照排队规则来确定对象产生的顺序,通常与他们被插入的顺序相同.

         (二)Map,一组成对的”键值对”对象,允许你使用键来查找值.

 

三.添加一组元素

Arrays asList

public static <T> List<T> asList(T... a) {

 

Collection addAll

boolean addAll(Collection<? extends E> c);

 

Collections addAll

public static <T> boolean addAll(Collection<? super T> c, T... elements)

 

ArrayList

public ArrayList(Collection<? extends E> c)

 

    Collection<Integer> collection =

      new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));

    Integer[] moreInts = { 6, 7, 8, 9, 10 };

    collection.addAll(Arrays.asList(moreInts));

    Collections.addAll(collection, 11, 12, 13, 14, 15);

    Collections.addAll(collection, moreInts);

    List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);

    list.set(1, 99);

    // list.add(21); // Runtime error because the

                     // underlying array cannot be resized.

四.容器的打印

  static Collection fill(Collection<String> collection) {

        collection.add("rat");

        collection.add("cat");

        collection.add("dog");

        collection.add("dog");

        return collection;

    }

 

    static Map fill(Map<String, String> map) {

        map.put("rat", "Fuzzy");

        map.put("cat", "Rags");

        map.put("dog", "Bosco");

        map.put("dog", "Spot");

        return map;

    }

 

    public static void main(String[] args) {

        print(fill(new ArrayList<String>()));

        print(fill(new LinkedList<String>()));

        print(fill(new HashSet<String>()));

        print(fill(new TreeSet<String>()));

        print(fill(new LinkedHashSet<String>()));

 

        print(fill(new HashMap<String, String>()));

        print(fill(new TreeMap<String, String>()));

        print(fill(new LinkedHashMap<String, String>()));

    }

输出:

[rat, cat, dog, dog]

[rat, cat, dog, dog]

[rat, cat, dog]

[cat, dog, rat]

[rat, cat, dog]

{rat=Fuzzy, cat=Rags, dog=Spot}

{cat=Rags, dog=Spot, rat=Fuzzy}

{rat=Fuzzy, cat=Rags, dog=Spot}

 

 

Collection, Map 是Java容器类库中的两种主要类型, 区别在于容器中每个”槽”保存的元素个数.

         Collection在每个槽中只能保存一个元素. List,它以特定的顺序保存一组元素;Set,元素不能重复;Queue,只允许在容器的一端插入对象,并从另外一端移除对象.

         Map在每个槽内保存了两个对象,即键和与之相关联的值.

         ArrayList和LinkedList都是List类型,都按照被插入的顺序保存元素.LinkedList包含的操作多于ArrayList. 二者的区别在于某些操作的性能.

         HashSet,TreeSet,LinkedHashSet存储元素的方式不同.HashSet是最快获取元素的方式.存储没有顺序;TreeSet按照比较结果的升序保存对象;LinkedHashSet,按照被添加的顺序保存对象.

         Map也被称为关联数组,可以用键来查找对象,可以看做是一个简单的数组库,键所关联的对象为值.Map会自动地调整尺寸.

         HashMap提供了最快的查找速度;TreeMap按照比较结果的升序保存键;LinkedHashMap按照插入顺序保存键,同事还保留了HashMap的查询速度.

         打印一个数组:

Arrays

public static String toString(Object[] a)

 

五.List

         有两种类型的List:

         ArrayList,随机访问元素速度快.但是在List的中间插入和移除元素较慢.

         LinkedList,插入删除速度快,顺序访问较快,随机访问速度慢.

public boolean add(E e)

public void add(int index, E element)

boolean addAll(int index, Collection<? extends E> c);

public boolean contains(Object o)

public boolean containsAll(Collection<?> c)

public E remove(int index)

public boolean remove(Object o)

public E get(int index)

public int indexOf(Object o) {

public int lastIndexOf(Object o)

public List<E> subList(int fromIndex, int toIndex)

boolean removeAll(Collection<?> c);

boolean isEmpty();

public Object[] toArray()

public <T> T[] toArray(T[] a)

 

Collections.sort(List)

Collections

public static <T extends Comparable<? super T>> void sort(List<T> list) {

        list.sort(null);

}

 

ArrayList

public void sort(Comparator<? super E> c)

public boolean retainAll(Collection<?> c) //交集

public ArrayList()

public ArrayList(Collection<? extends E> c)

Collections

public static void shuffle(List<?> list, Random rnd)

Random rand = new Random(47);

Collections.shuffle(List, rand);

 

Arrays

public static <T> List<T> asList(T... a)

 

 

六.迭代器

Java的Iterator只能单向移动,这个Iterator只能用来:

  • 使用方法iterator()要求容器返回一个Iterator.Iterator将准备好返回序列的第一个元素.
  • 使用next()获得序列中的下一个元素.
  • 使用hasNext()检查序列中是否还有元素
  • 使用remove()将迭代器新近返回的元素删除.

 

示例:

List<String> list = new ArrayList<String>(Arrays.asList("A", "B", "C"));

Iterator<String> iterator1 = list.iterator();

while(iterator1.hasNext()){

    System.out.print(iterator1.next() + " ");

}

System.out.println();

for(String str : list){

    System.out.print(str + " ");

}

System.out.println();

Iterator<String> iterator2 = list.iterator();

for(int i = 0; i < 2; i++){

    iterator2.next();

    iterator2.remove();

}

System.out.println(list);

 

输出结果:

A B C

A B C

[C]

 

ListIterator:是更加强大的Iterator的子类型.

  • 可以双向移动
  • 可以产生前一个和后一个元素的索引
  • 使用set()替换元素
  • listIterator(n)创建一个执行列表索引为n的元素处的ListIterator

 

        List<Pet> pets = Pets.arrayList(8);

        ListIterator<Pet> it = pets.listIterator();

        while (it.hasNext())

            System.out.print(it.next() + ", " + it.nextIndex() + ", " +

            it.previousIndex() + "; ");

            System.out.println();

        // Backwards:

        while (it.hasPrevious())

            System.out.print(it.previous().id() + " ");

        System.out.println();

        System.out.println(pets);

        it = pets.listIterator(3);

        while (it.hasNext()) {

            it.next();

            it.set(Pets.randomPet());

        }

        System.out.println(pets);

输出:

Rat, 1, 0; Manx, 2, 1; Cymric, 3, 2; Mutt, 4, 3; Pug, 5, 4; Cymric, 6, 5; Pug, 7, 6; Manx, 8, 7;

7 6 5 4 3 2 1 0

[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Manx]

[Rat, Manx, Cymric, Cymric, Rat, EgyptianMau, Hamster, EgyptianMau]

 

七.LinkedList

LinkedList实现了基本的List接口,但是在List中进行插入和移除比ArrayList更高效,在随机访问操作要逊色一些.

         LinkedList添加了可以使其用作栈,队列或双端队列的方法.

     LinkedList<Pet> pets = new LinkedList<Pet>(Pets.arrayList(5));

        print(pets);

        // Identical:

        print("pets.getFirst(): " + pets.getFirst());

        print("pets.element(): " + pets.element());

        // Only differs in empty-list behavior:

        print("pets.peek(): " + pets.peek());

        // Identical; remove and return the first element:

        print("pets.remove(): " + pets.remove());

        print("pets.removeFirst(): " + pets.removeFirst());

        // Only differs in empty-list behavior:

        print("pets.poll(): " + pets.poll());

        print(pets);

        pets.addFirst(new Rat());

        print("After addFirst(): " + pets);

        pets.offer(Pets.randomPet());

        print("After offer(): " + pets);

        pets.add(Pets.randomPet());

        print("After add(): " + pets);

        pets.addLast(new Hamster());

        print("After addLast(): " + pets);

        print("pets.removeLast(): " + pets.removeLast());

    }

输出:

[Rat, Manx, Cymric, Mutt, Pug]

pets.getFirst(): Rat

pets.element(): Rat

pets.peek(): Rat

pets.remove(): Rat

pets.removeFirst(): Manx

pets.poll(): Cymric

[Mutt, Pug]

After addFirst(): [Rat, Mutt, Pug]

After offer(): [Rat, Mutt, Pug, Cymric]

After add(): [Rat, Mutt, Pug, Cymric, Pug]

After addLast(): [Rat, Mutt, Pug, Cymric, Pug, Hamster]

pets.removeLast(): Hamster

 

八.Stack

不建议使用java.util.Stack.

可以使用以下Stack, 或者编写一个包含LinkedList的类,用组合的方式使用LinkedList.

//: net/mindview/util/Stack.java

// Making a stack from a LinkedList.

package net.mindview.util;

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具有与Collection完全一样的接口,没有额外的功能,实际上 Set就是Collection, 只是行为不同.

HashSet使用的是散列函数.

TreeSet将元素存储在红-黑数据结构中.

LinkedHashList使用了散列,使用链表来维护

    Set<String> set1 = new HashSet<String>();

    Collections.addAll(set1,

      "A B C D E F G H I J K L".split(" "));

    set1.add("M");

    print("H: " + set1.contains("H"));

    print("N: " + set1.contains("N"));

    Set<String> set2 = new HashSet<String>();

    Collections.addAll(set2, "H I J K L".split(" "));

    print("set2 in set1: " + set1.containsAll(set2));

    set1.remove("H");

    print("set1: " + set1);

    print("set2 in set1: " + set1.containsAll(set2));

    set1.removeAll(set2);

    print("set2 removed from set1: " + set1);

    Collections.addAll(set1, "X Y Z".split(" "));

print("'X Y Z' added to set1: " + set1);

输出:

H: true

N: false

set2 in set1: true

set1: [A, B, C, D, E, F, G, I, J, K, L, M]

set2 in set1: false

set2 removed from set1: [A, B, C, D, E, F, G, M]

'X Y Z' added to set1: [A, B, C, D, E, F, G, M, X, Y, Z]

 

默认情况下TreeSet会按照先大写后小写的顺序去排序,如果想让大小写无关,可以在TreeSet构造器中传入 TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

 

十.Map

    Random rand = new Random(47);

    Map<Integer,Integer> m =

      new HashMap<Integer,Integer>();

    for(int i = 0; i < 10000; i++) {

      // Produce a number between 0 and 20:

      int r = rand.nextInt(20);

      Integer freq = m.get(r);

      m.put(r, freq == null ? 1 : freq + 1); // put为增加

    }

System.out.println(m);

输出:

{0=481, 1=502, 2=489, 3=508, 4=481, 5=503, 6=519……

 

    Map<String,Pet> petMap = new HashMap<String,Pet>();

    petMap.put("My Cat", new Cat("Molly"));

    petMap.put("My Dog", new Dog("Ginger"));

    petMap.put("My Hamster", new Hamster("Bosco"));

    print(petMap);

    Pet dog = petMap.get("My Dog");  // 获取一个element

    print(dog);

    print(petMap.containsKey("My Dog")); // 是否包含某个 key

print(petMap.containsValue(dog));    // 是否包含某个 value

输出:

{My Dog=Dog Ginger, My Cat=Cat Molly, My Hamster=Hamster Bosco}

Dog Ginger

true

true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值