容器 就是存放数据的一个集合
(java提供了一个接口专门去约束我们容器的实现类)
Set: does not allow duplicate objects toenter the collection of elements
SortedSet: similar to set except that theelements in the set are stored in ascending order
List: is ordered, maintain an order asobjects are added and removed from the collection,can also contain duplicateentries of objects
Map: stores objects that are identifiedby unique keys, and may not store duplicate keys
SortedMap: similar to Map, except the objectsare stored in ascending order according to their keys
即:
• Collection 接口:定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。
– Set 中的数据对象没有顺序且不可以重复。
– List 中的数据对象有顺序且可以重复。
– Map 接口定义了存储“键(key)- 值(value)映射对”的方法。
• Collection 表示一组对象,它是集中,收集的意思,就是把一些数据收集起来。
• Collection函数库是在java.util 包下的一些接口和类,类是用来产生对象存放数据用的,而接口是访问数据的方式。
• Collection函数库与数组的两点不同:
1.数组的容量是有限制的,而Collection库没有这样的限制,它容量可以自动的调节 。
2.Collection函数库只能用来存放对象,而数组没有这样的限制。
• Collection接口是Collection层次结构 中的根接口,它定义了一些最基本的访问方法,让我们能用统一的方式通过它或它的子接口来访问数据。
• 区别:Collection代表一组对象, Collection函数库就是java中的集合框架,Collection接口,是这个集合框架中的根接口。
• 存放在Collection 库中的数据,被称为元素(element) 。
Demo
<span style="font-size:18px;"><span style="font-size:18px;">public class Person { private intid; private Stringname; public Person(int id, String name) { this. id= id; this. name = name; } public intgetId() { return id; } public StringgetName() { return name; } public voidsetId (int id) { this. id= id; } public voidsetName (String name) { this.name = name; } public StringtoString() { return “id: ” + id + “|name: ” + name; } } ======================================================================== import java.util.*; public class CollectionTest1 { public staticvoid main (String[] args) { Collectionc = new HashSet(); c. add(new Person(1, “c++")); c. add(new Person(2, “java")); System.out.println(c. size() + ": " + c); System.out.println("contains: " + c. contains (new Person(2, "java"))); System.out.println(c. remove (new Person(2, " java"))); System.out.println(c. size() + ": " + c); } }</span></span>
输出结果:
• 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。
• Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
• Iterator接口定义了如下方法:
Demo
<span style="font-size:18px;"><span style="font-size:18px;">import java.util.*; public class IteratorTest1 { public staticvoid main(String[] args) { Collectionc = new ArrayList(); c.add("good"); c.add("morning"); c.add("key"); c.add("happy"); for(Iterator it = c.iterator(); it.hasNext(); ) { Stringtem = (String) it.next(); if(tem.trim().length() <= 3) { it.remove(); } } System.out.println(c); } } </span></span>
• Set 接口是Collection接口的子接口,Set接口没有提供额外的方法,Set接口的特性是容器类中的元素是没有顺序的,而且不可以重复。
• Set 容器可以与数学中“集合”的概念相对应。
• J2SDK API中所提供的 Set 容器类有 HashSet,TreeSet 等。
<span style="font-size:18px;">import java.util.*; public class SetTest { public staticvoid main (String[] args) { Set s =new HashSet(); s.add("hello"); s.add("world"); s.add(new Integer(4)); s.add(new Double(1.2)); s.add("hello"); // 相同的元素不会被加入 System.out.println(s); } } </span>
• List接口是Collection的子接口,实现List接口的容器类中的元素是有顺序的,而且可以重复。
• List 容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
• J2SDK 所提供的 List 容器类有 ArrayList,LinkedList 等。
<span style="font-size:18px;"><span style="font-size:18px;">import java.util.*; public class ListTest { public staticvoid main(String[] argc) { List l1= new ArrayList(); for (inti = 0; i <= 5; i++) l1.add("a"+ i); System.out.println(l1); list.add(3,"a100"); System.out.println(l1); list.set(6,"a200"); System.out.println(list); System.out.print((String)list.get(2) + " "); System.out.println(list.indexOf("a3")); list.remove(1); System.out.println(list); } }</span></span>
类 java.util.Collections 提供了一些静态方法实现了基于List容器的一些常用算法 。
Demo
<span style="font-size:18px;"><span style="font-size:18px;">import java.util.*; public class CollectionsTest { publicstatic void main(String[] argc) { List aList =new ArrayList(); for (int i = 0;i < 5; i++) aList.add("a"+ i); System.out.println(aList); Collections.shuffle(aList);// 随机排列 System.out.println(aList); Collections.reverse(aList);// 逆续 System.out.println(aList); Collections.sort(aList);// 排序 System.out.println(aList); System.out.println(Collections.binarySearch(aList,"a2")); Collections.fill(aList,"hello"); System.out.println(aList); } } </span></span>
问题:上面的算法根据什么确定集合中对象的“大小”顺序?
• 所有可以“排序”的类都实现了java.lang.Comparable 接口,Comparable接口中只有一个方法
public int compareTo(Objectobj);
该方法:
• 实现了Comparable 接口的类通过实现 comparaTo 方法从而确定该类对象的排序方式。
<span style="font-size:18px;"><span style="font-size:18px;">public class Student implements Comparable { private Stringname; private Integerscore; publicStudent(String name, int score) { this.name =name; this.score =new Integer(score); } public intcompareTo(Object o) { Student n =(Student) o; int a =score.compareTo(n.score); return (a !=0 ? a : name.compareTo(n.name)); } public StringtoString() { return"name: " + name + " score: " + score.toString(); } } import java.util.*; public class StudentTest { public static voidmain(String[] args) { List l1 = newLinkedList(); l1.add(newStudent(“ttt", 66)); l1.add(newStudent(“bbb", 77)); l1.add(newStudent(“ccc", 99)); l1.add(newStudent(“fff", 88)); l1.add(newStudent(“aaa", 66)); System.out.println(l1); Collections.sort(l1); System.out.println(l1); } }</span></span>
• 实现Map接口的类用来存储键(key)-值(value) 对。
• Map 接口的实现类有HashMap和TreeMap等。
• Map类中存储的键-值对通过键来标识,所以键值不能重复。
<span style="font-size:18px;"><span style="font-size:18px;">import java.util.*; public class MapTest { public staticvoid main(String args[]) { Map m1 =new HashMap(); Map m2 =new TreeMap(); m1.put("one",new Integer(1)); m1.put("two",new Integer(2)); m1.put("three",new Integer(3)); m2.put("A",new Integer(1)); m2.put("B",new Integer(2)); System.out.println(m1.size()); System.out.println(m1.containsKey("one")); System.out.println(m2.containsValue(newInteger(1))); if(m1.containsKey("two")) { inti = ((Integer) m1.get("two")).intValue(); System.out.println(i); } Map m3 =new HashMap(m1); m3.putAll(m2); System.out.println(m3.size()); } }</span></span>
泛型的作用就是为了约束你传入对象的类型;
通俗来讲:传进去什么,拿出来什么。
• 起因:
– JDK1.4以前类型不明确:
• 装入集合的类型都被当作Object对待,从而失去自己的实际类型。
• 从集合中取出时往往需要转型,效率低,容易产生错误。
• 解决办法:
– 在定义集合的时候同时定义集合中对象的类型
• 可以在定义Collection的时候指定
• 也可以在循环时用Iterator指定
• 好处:
– 增强程序的可读性和稳定性
<span style="font-size:18px;"><span style="font-size:18px;">import java.util.*; public class MapTest1 { public staticvoid main(String args[]) { Map<String,Integer> m = new HashMap<String, Integer>(); for(int i = 0; i < 5; i++) { m.put(String.valueOf(i),1); } for(int i = 0; i < 5; i++) { m.put(String.valueOf(i),1); } System.out.println(m.size()+ " distinct words detected:"); System.out.println(m); Set<String>set = m.keySet(); Iteratorit = set.iterator(); while(it.hasNext()) { System.out.println(m.get(it.next())); } } }</span></span>
• 增强的for循环对于遍历array 或 Collection的时候相当简便
• 缺陷:
– 数组:
• 不能方便的访问下标值
– 集合:
• 与使用Iterator相比,不能方便的删除集合中的内容
• 总结:
– 除了简单遍历并读出其中的内容外,不建议使用增强for
JAVA提供的这个接口专门约束我们容器的实现类,从很大程度上减轻了我们设计人员的负担,提高效率。
容器类的总结相对来说是比较零散的知识点,很难完整的讲述出来,在不断的使用中,可以得到更好地理解。