Java&&持有对象(容器小结)

如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这是一个非常简单的程序。

-------<Thinking in Java>

通常,程序总是根据运行时才知道的某些条件去创建新对象。对象数量,对象类型尚且不能确定。为了解决这个问题,满足程序员需要在任意时刻和任意位置创建任意数量对象的要求。Java实用类库提供了一套相当完整的容器类来解决这个问题(因为数组受到固定尺寸的左右)。其中基本的类型是List,Set,Queue和Map。这些对象类型也称为集合类,但由于java的类库中实用了collection这个名字来指代类库的一个特殊子集,所以我使用了范围更广的术语“容器”称呼他们。

11.1 泛型和类型安全的容器

要想定义用来保存Apple对象的ArrayList,你可以申明ArrayList<Apple>,而不仅仅只是ArrayList,其中尖括号括起来的是类型参数(可以有多个),它指定了这个容器实例可以保存的类型。此时将元素从List中取出来时,类型转换也不再是必须的了。因为List知道它保存的是什么类型,因此它会在get()时替你执行转型。

11.2 基本概念

容器类类型库的用途是“保存对象”,并将其划分为两个不同的概念:

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

2)Map:一组成对的“键值对”对象,允许你使用键来查找值。


名称


类型


实现


优点


缺点


排序


可重复


迭代性


同步


Iterable


接口


F


T


T


F


Collection


接口


F


T


T


F


Queue


接口


F


T


T


F


PriorityQueue


堆(一种二叉树)


优先级队列


T


T


T


F


List


接口


按索引排序


T


T


T


F


LinkedList



双向循环链表


T


T


T


F


ArrayList



数组


查找


增删


T


T


T


F


Vector



数组


增删


查找


T


T


T


T


Stack




T


T


T


T


Set


接口


F


F


T


F


TreeSet



T


F


T


F


HashSet



F


F


T


F


Map


接口


F


F


T


F


HashMap



查找


F


F


T


F


TreeMap



排序


T


F


T


F


HashTable


F


F


T


T


Properties


HashTable的子类,表示了一个持久的属性集。

11.2.1 Collection接口(省略常用的方法)

[java] view
plain
copy

  1. boolean add(Object obj) 添加一个Object元素
  2. boolean addAll(Collection c)
  3. boolean contains(Object obj)  判断obj是否是调用类集的一个元素(属于)
  4. boolean containsAll(Collection c)  判断c是否是调用类集的子集(包含)
  5. boolean equals(Collection c) 判断c是否与调用类集相等
  6. int hashCode() 返回调用类集的hash码
  7. Iterator iterator() 返回调用类集的迭代程序
  8. boolean removeAll(Collection c) 从调用类集中去掉所有c中包含的元素(差集)
  9. boolean retainAll(Collection c) 从调用类集中去掉包含在c中以外的元素(补集)
  10. Object[] toArray() 返回类集的元素组成的数组
  11. void clear()
  12. boolean isEmpty()
  13. int size()
  14. //类集包含一个add(Object obj)方法,因此可以包含任意Object数据,但是不能直接存储:int,char,double等数据。可以使用下面的方法实现:
  15. ArrayList a=new ArrayList();
  16. a.add(new Integer(1));
  17. a.add(new Integer(2));
  18. //……
  19. //当类集不能被修改时,可能引发 UnsupportedOperationException异常。企图将一个不兼容的对象加入到一个类集中时可能引发ClassCastException//异常。

11.3 添加一组元素

[java] view
plain
copy

  1. //: holding/AddingGroups.java
  2. // Adding groups of elements to Collection objects.
  3. import java.util.*;
  4. public class AddingGroups {
  5. public static void main(String[] args) {
  6. Collection<Integer> collection =
  7. new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
  8. Integer[] moreInts = { 6, 7, 8, 9, 10 };
  9. collection.addAll(Arrays.asList(moreInts));
  10. // Runs significantly faster, but you can‘t
  11. // construct a Collection this way:
  12. Collections.addAll(collection, 11, 12, 13, 14, 15);
  13. Collections.addAll(collection, moreInts);
  14. // Produces a list "backed by" an array:
  15. List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
  16. list.set(1, 99); // OK -- modify an element
  17. // list.add(21); // Runtime error because the
  18. // underlying array cannot be resized.
  19. }
  20. } ///:~

你也可以直接使用Arrays.asList()的输出,将其当作List,但是在这种情况下,其底层表示的是数组,因此不能调整尺寸。

Arrays.asList()方法的限制是它对所产生的List的类型做出了最理想的假设,而并没有注意你会对它赋予什么样的类型。

[java] view
plain
copy

  1. //: holding/AsListInference.java
  2. // Arrays.asList() makes its best guess about type.
  3. import java.util.*;
  4. class Snow {}
  5. class Powder extends Snow {}
  6. class Light extends Powder {}
  7. class Heavy extends Powder {}
  8. class Crusty extends Snow {}
  9. class Slush extends Snow {}
  10. public class AsListInference {
  11. public static void main(String[] args) {
  12. List<Snow> snow1 = Arrays.asList(
  13. new Crusty(), new Slush(), new Powder());
  14. // Won‘t compile:
  15. // List<Snow> snow2 = Arrays.asList(
  16. //   new Light(), new Heavy());
  17. // Compiler says:
  18. // found   : java.util.List<Powder>
  19. // required: java.util.List<Snow>
  20. // Collections.addAll() doesn‘t get confused:
  21. List<Snow> snow3 = new ArrayList<Snow>();
  22. Collections.addAll(snow3, new Light(), new Heavy());
  23. // Give a hint using an
  24. // explicit type argument specification:
  25. List<Snow> snow4 = Arrays.<Snow>asList(
  26. new Light(), new Heavy());
  27. }
  28. } ///:~

11.4 容器的打印

[java] view
plain
copy

  1. //: holding/PrintingContainers.java
  2. // Containers print themselves automatically.
  3. import java.util.*;
  4. import static net.mindview.util.Print.*;
  5. public class PrintingContainers {
  6. static Collection fill(Collection<String> collection) {
  7. collection.add("rat");
  8. collection.add("cat");
  9. collection.add("dog");
  10. collection.add("dog");
  11. return collection;
  12. }
  13. static Map fill(Map<String,String> map) {
  14. map.put("rat", "Fuzzy");
  15. map.put("cat", "Rags");
  16. map.put("dog", "Bosco");
  17. map.put("dog", "Spot");
  18. return map;
  19. }
  20. public static void main(String[] args) {
  21. print(fill(new ArrayList<String>()));
  22. print(fill(new LinkedList<String>()));
  23. print(fill(new HashSet<String>()));
  24. print(fill(new TreeSet<String>()));
  25. print(fill(new LinkedHashSet<String>()));
  26. print(fill(new HashMap<String,String>()));
  27. print(fill(new TreeMap<String,String>()));
  28. print(fill(new LinkedHashMap<String,String>()));
  29. }
  30. } /* Output:
  31. [rat, cat, dog, dog]
  32. [rat, cat, dog, dog]
  33. [dog, cat, rat]
  34. [cat, dog, rat]
  35. [rat, cat, dog]
  36. {dog=Spot, cat=Rags, rat=Fuzzy}
  37. {cat=Rags, dog=Spot, rat=Fuzzy}
  38. {rat=Fuzzy, cat=Rags, dog=Spot}
  39. *///:~

ArrayList和LinkedList都是List类型,从输出可以看出,它们都是按照被插入的顺序保存元素。两者不同之处不仅在于执行某些类型的操作时的性能,而且LinkedList包含的操作也多余ArrayList。

HashSet,TreeSet和LinkedHashSet都是Set类型,输出显示在Set中,每个相同的项只保存一次,但是输出也显示了不同的Set实现存储元素的方式也不同。

你不需要指定Map的尺寸,因为它会自动地调整尺寸。

HashMap提供了最快的查找技术,也没有按照任何明显的顺序来保存其元素。TreeMap按照比较结果的升序保存键,而LinkedHashMap则按照插入顺序保存键,同时还保留了HashMap的查询速度。

11.5 List

List接口(从Collection继承而来,使用基于0的下标)

[java] view
plain
copy

  1. void add(int index,Object obj) 插入点以后的元素将后移
  2. boolean addAll(int index,Collection c) 如果调用列表改变了,返回true,否则返回false
  3. Object get(int index)
  4. int indexOf(Object obj) 返回obj对象在列表中的索引,不存在返回-1
  5. int lastIndexOf(Object obj) 返回obj在列表中的最后一个实例的下标,不存在返回-1
  6. ListIterator listIterator()
  7. ListIterator listIterator(int index) 返回index开始的迭代程序
  8. Object set(int index,Object obj) 对列表index处的值进行修改
  9. List subList(int start,int end) 从start到end-1

11.6 迭代器

iterator实现Iterator接口或者ListIterator接口。

Iterator接口

[java] view
plain
copy

  1. boolean hasNext()
  2. Object next() 如果没有下一个元素则引发NoSuchElementException异常。
  3. void remove() 删除当前元素,如果试图在调用next()方法后调用remove()方法则引发IllegalStateException异常。
  4. ListIterator接口
  5. void add(Object obj) 将一个元素插入到当前元素之前,调用next()方法将返回该元素。
  6. boolean hasNext()
  7. boolean hasPrevious()
  8. Object next() 如果不存在引发NoSuchElementException
  9. int nextIndex() 如果不存在返回列表的大小
  10. void remove()
  11. void set(Object obj) 修改当前元素
  12. public void test1() {
  13. ArrayList al = new ArrayList();
  14. for (int i = 1; i < 10; i ) {
  15. al.add("ArrayList Element:" i);
  16. }
  17. Iterator itr = al.listIterator();
  18. while (itr.hasNext()) {
  19. Object obj = itr.next();
  20. System.out.println(obj);
  21. }
  22. }
  23. public void test2() {
  24. HashSet hs = new HashSet();
  25. System.out.println("HashSet");
  26. for (int i = 1; i < 10; i ) {
  27. hs.add("HashSet Element:" i);
  28. }
  29. Iterator itr = hs.iterator();
  30. while (itr.hasNext()) {
  31. Object obj = itr.next();
  32. System.out.println(obj);
  33. }
  34. }
  35. public void test3() {
  36. TreeSet ts = new TreeSet();
  37. System.out.println("TreeSet");
  38. for (int i = 1; i < 10; i ) {
  39. ts.add("TreeSet Element:" i);
  40. }
  41. Iterator itr = ts.iterator();
  42. while (itr.hasNext()) {
  43. Object obj = itr.next();
  44. System.out.println(obj);
  45. }
  46. }
  47. public void test4()
  48. {
  49. HashMap hm=new HashMap();
  50. for ( int i=0;i<10;i )
  51. {
  52. hm.put("item" i,"value" i);
  53. }
  54. Set set=hm.entrySet();
  55. Iterator itr=set.iterator();
  56. while (itr.hasNext())
  57. {
  58. Map.Entry me=(Map.Entry)itr.next();

11.7 LinkedList

LinkedList还添加了可以使其用作栈、队列或双端队列的方法。

11.8 Stack

[java] view
plain
copy

  1. //: net/mindview/util/Stack.java
  2. // Making a stack from a LinkedList.
  3. package net.mindview.util;
  4. import java.util.LinkedList;
  5. public class Stack<T> {
  6. private LinkedList<T> storage = new LinkedList<T>();
  7. public void push(T v) { storage.addFirst(v); }
  8. public T peek() { return storage.getFirst(); }
  9. public T pop() { return storage.removeFirst(); }
  10. public boolean empty() { return storage.isEmpty(); }
  11. public String toString() { return storage.toString(); }
  12. } ///:~

11.9 Set

Set接口(从Collection派生,没有定义新的方法)

Set不允许有重复的元素,用Iterator()方法来区分重复与否。

对Set调用add(Object obj)方法,如果obj已经存在集合中,将返回false。

11.9.1 SortedSet接口

[java] view
plain
copy

  1. Comparator comparator() 返回调用排序集合的比较函数,如果改集合使用自然顺序,则返回null
  2. Object first() 返回被排序集合的第一个元素
  3. SortedSet headSet(Object end) 返回一个包含小于end元素的SortedSet
  4. Object last() 返回调用排序集合的最后一个元素
  5. SortedSet subSet(Object start,Object end) 包括从start到end-1
  6. SortedSet tailSet(Object start) 返回包含大于等于start的元素
  7. ArrayList扩展AstractList类,并执行List接口。ArrayList支持动态长度的数组。
  8. LinkList扩展了AbstractSequentialList,执行List接口。提供连接列表。
  9. HashSet扩展AbstractSet实现Set接口,元素没有顺序。对于大集合提供常量级基本操作。
  10. TreeSet使用树来存储的Set,对象按升序存储。访问和检索非常快。

11.10 Map

[java] view
plain
copy

  1. (1) 添加、删除操作:
  2.   Object put(Object key, Object value): 将互相关联的一个关键字与一个值放入该映像。如果该关键字已经存在,那么与此关键字相关的新值将取代旧值。方法返回关键字的旧值,如果关键字原先并不存在,则返回null
  3.   Object remove(Object key): 从映像中删除与key相关的映射
  4.   void putAll(Map t): 将来自特定映像的所有元素添加给该映像
  5.   void clear(): 从映像中删除所有映射
  6.   “键和值都可以为null。但是,您不能把Map作为一个键或值添加给自身。”
  7.   (2) 查询操作:
  8.   Object get(Object key): 获得与关键字key相关的值,并且返回与关键字key相关的对象,如果没有在该映像中找到该关键字,则返回null
  9.   boolean containsKey(Object key): 判断映像中是否存在关键字key
  10.   boolean containsValue(Object value): 判断映像中是否存在值value
  11.   int size(): 返回当前映像中映射的数量
  12.   boolean isEmpty() :判断映像中是否有任何映射
  13.   (3) 视图操作 :处理映像中键/值对组
  14.   Set keySet(): 返回映像中所有关键字的视图集
  15.   “因为映射中键的集合必须是唯一的,您用Set支持。你还可以从视图中删除元素,同时,关键字和它相关的值将从源映像中被删除,但是你不能添加任何元素。”
  16.   Collection values():返回映像中所有值的视图集
  17.   “因为映射中值的集合不是唯一的,您用Collection支持。你还可以从视图中删除元素,同时,值和它的关键字将从源映像中被删除,但是你不能添加任何元素。”
  18.   Set entrySet(): 返回Map.Entry对象的视图集,即映像中的关键字/值对
  19.   “因为映射是唯一的,您用Set支持。你还可以从视图中删除元素,同时,这些元素将从源映像中被删除,但是你不能添加任何元素。”

11.11 Queue

11.12 Collection和Iterator

11.13 Foreach与迭代器

之所以能够工作,是因为java SE5引入了新的被称为Iterable的接口,该接口包含一个能够产生Iterator的iterator()方法,并且Iterable接口被foreach用来在序列中移动。因此如果你创建了任何实现Iterable的类,都可以将它用于foreach语句中:

[java] view
plain
copy

  1. //: holding/IterableClass.java
  2. // Anything Iterable works with foreach.
  3. import java.util.*;
  4. public class IterableClass implements Iterable<String> {
  5. protected String[] words = ("And that is how " +
  6. "we know the Earth to be banana-shaped.").split(" ");
  7. public Iterator<String> iterator() {
  8. return new Iterator<String>() {
  9. private int index = 0;
  10. public boolean hasNext() {
  11. return index < words.length;
  12. }
  13. public String next() { return words[index++]; }
  14. public void remove() { // Not implemented
  15. throw new UnsupportedOperationException();
  16. }
  17. };
  18. }
  19. public static void main(String[] args) {
  20. for(String s : new IterableClass())
  21. System.out.print(s + " ");
  22. }
  23. } /* Output:
  24. And that is how we know the Earth to be banana-shaped.
  25. *///:~

11.4 总结

简单容器分类:

时间: 2024-10-10 08:48:19

Java&&持有对象(容器小结)的相关文章

JAVA 持有对象——容器初探

引言 如果一个程序只包含固定数量的且其生命周期都是已知对象,那么这是一个非常简单的程序--<think in java> 了解容器前,先提出一个问题,ArrayList和LinkedList谁的处理速度更快呢? 一 持有对象的方式 在Java中,我们可以使用数组来保存一组对象.但是,数组是固定大小的,在一般情况下,我们写程序时并不知道将需要多少个对象,因此数组固定大小对于编程有些受限. java类库中提供了一套相当完整的容器类来解决这个问题,其中基本类型有List,Queue,Set,Map,

java 持有对象总结

java提供了大量的持有对象的方式: 1)数组将数字和对象联系起来,它保存类型明确的对象,查询对象时,不需要对结果做类型转换,它可以时多维的,可以保存基本数据类型的数据,但是,数组一旦生成,其容量就不能改变 2)Collection保存单一的元素,而Map保存相关联的键值对.有了java泛型,你就可以指定容器中存放的对象类型,因此你就不会将错误类型的对象放置到容器中,并且从容器中取出元素时,不必进行类型转换,各种Collection和各种Map都快以在你向其中添加更多的元素时,自动调整其尺寸.容

Java 持有对象学习笔记

1. 持有对象:说的就是容器,持有别的对象的对象: 2. Interator 可以移除由 next() 产生的最后一个对象,这意味着在调用一个 remove() 之前必须先调用 next() : 3. 迭代器统一了对容器的访问方式: 4. 程序通常是根据运行时才知道的某些条件去创建新对象: 5. 需要在任意时刻和任意位置创建任意数量的对象: 6. List Set Queue Map,Collection Container: 7. 通过使用泛型,就可以在编译器防止将错误类型的对象放置在容器中,

Java持有对象的方法——容器

通常,程序总是根据运行时才知道的某些条件去创建新对象. 在此之前,并不知道所需对象的数量,甚至不知道确切的类型. 所以,为解决这个普遍的编程问题,需要在任意时刻和任意位置创建任意数量的对象: 首先,不能依靠创建命名的引用来持有每一个对象了: MyType aReference; 原因: 不知道实际上会需要多少这样的引用.大多数语言会提供数组的方式保存对象(应该说是对象的引用) 但是,数组虽然是保存一组对象或者基本类型数据的有效方式,其由于具有固定的尺寸,在一般情况下十分受限. 解决: Java使

java持有对象【2】ArrayList容器续解

此为JDK API1.6.0对ArrayList的解释. ArrayList 使用java泛型创建类很复杂,但是应用预定义的泛型很简单.例如,要想定义用来保存Apple对象的ArrayList,可以声明ArrayList<Apple>,尖括号内为类型参数,(可以为多个).它指定了容器可以保存的类型. 通过使用泛型,可以在编译期防止将错误类型的对象放置到容器中. ArrayList向上转型为List. 应该注意到,在将元素从List中取出时,类型转换不是必须的了.因为List在调用get()时会

java面向对象---对象容器

泛型类--ArrayList<>; 2.对象数组中的每个元素都是对象的管理者而并非对象本身!!!!! 3.java类的基本数据类型 基本数据类型 包装类 byte Byte short Short int Integer long Long float Float double Double char Character boolean Boolean 4.for-each循环在对象数组中的应用 在基本类型的数组中,比如 int[],使用for-each 循环可以遍历数组中的值,但是不能对数组

Java持有对象--根据编程思想

1:用ArrayList来添加add数据,和size知道ArrayList的容器元素的个数,但是可以添加不同类型的元素,这样就会报错,但是JavaSE5用注解解决了这一问题(@SuppressWarnings("all")),抑制了错误信息@SuppressWarning注解,表示不接受检查异常,还有就是使用泛型来规避 2:Java容器是用来保存对象,划分为两个不同的概念,collection和Map collection 有List必须按照顺序来插入数据,set不允许有重复的数据,Q

Java 持有对象

如果一个程序中只包含固定数量的且其生命周期都是已知的对象,那么这是一个简单的程序 通常程序总是根据运行时才知道的某些条件去创建对象,为解决这个普遍的编程问题,需要在任意时刻,任意位置创建任意数量的对象 java有多种方式保存对象,如数组,数组比较时候保存基本数据类型,但数组的尺寸固定,显得过于受限 Java 实用类库还提供了一套相当完整的容器来保存对象,其中基本的类型时Set,Queue和Map,这些对象类型也称为集合类或容器,java容器可以自动调整自己的尺寸. 容器还有一些其它特性,例如,S

java持有对象【1】容器类及ArrayList

如果一个程序只包含固定数量的且其生命周期都是已知的对象,那么这是一个非常简单的程序.  ----------java编程思想第十一章引言 java有许多方式引用对象,例如学过的数组,他是编译器支持的类型,用来保存一组对象的最有效方式.但是数组具有固定的尺寸,在此受限的情况下,就需学习java的容器类. 深入的学习就要去不停地阅读jdk.java使用类库提供了一套完整的容器类.其中基本类型是List,Set,Queue,Map.也称为集合类.java的类库中用了collection来指代该类库的一