第十一章 混乱不堪的容器类基础
哇,这一章真的是好混乱啊。
首先,要弄明白这些类的层次关系,层次关系错综复杂,只要知道主要的就好,去看jdk文档趴。
这一章的目的主要熟悉各种接口,为后面的内容做铺垫。
一、Collection接口
Collection接口是List、Queue、Set接口的基类。他们分别有不同的抽象类实现,AbstracCollection类是AbstractList类、AbstractQueue类、AbstractSet类的基类。
一、List
共同特点:按照被插入的顺序保存元素
1.ArrayList
特点:①由数组实现擅长于随机访问,但是插入删除元素较慢
(1)列表初始化方法:
每个Collection类型的类都有默认构造函数和参数为Collection的构造函数两种
import java.util.*; //初始化列表的三种方式 public class AddingGroups { public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<Integer> l = new ArrayList<Integer>(); Integer[] moreInts = {6,7,8,9,10}; //第一种使用Collections类提供的静态方法是首选的方式 Collections.addAll(l, 1,2,3,4,5); Collections.addAll(l, moreInts); System.out.println("第一种方式Collections.addAll():" + l); //第二种使用Arrays类的asList()方法,此方法由数组实现返回一个固定大小列表,不可增改 //因此常包装在容器中使用 ArrayList<Integer> l1 = new ArrayList<Integer>(Arrays.<Integer>asList(11,12,13,14,15)); System.out.println("第二方式Arrays.asList():" + l1); //第三种方式容器自身的方法 l.addAll(l); System.out.println("第三种方式:" + l); } }
输出:
第一种方式Collections.addAll():[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
第二方式Arrays.asList():[11, 12, 13, 14, 15]
第三种方式:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(2)ArrayList方法举例
Pet类对象都被定义为唯一的,任何两个Pet对象equals()的结果都是false,在equals()方法中可以定义判断两个对象相等的标准。
判断一个元素是否属于List,返回元素索引,删除元素等操作都会用到equals()方法,所以这些随着equals()方法实现的不同,便会有不同的效果。
import java.util.*; import typeinfo.pets.*; //ArrayList方法应用举例 public class ArrayListMethod2 { public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<Pet> l = Pets.arrayList(10); Rat r = new Rat(); System.out.println("[1]: " + l); //在数组列表末尾增加一个对象 l.add(r); System.out.println("[2]: " + l); //在2位置插入一个对象 l.add(2, new Pug()); System.out.println("[3]: " + l); //删除对象r l.remove(r); System.out.println("[4]: " + l); //删除位置2处的元素 l.remove(2); System.out.println("[5]: " + l); //清空列表 l.clear(); System.out.println("[6]: " + l); //将列表l1中元素加入到l中 ArrayList<Pet> l1 = Pets.arrayList(7); l.addAll(l1); System.out.println("[7]: " + l); //在l列表3位置插入l l.addAll(3, l); System.out.println("[8]: " + l); //打印列表大小 System.out.println("[9]: size " + l.size()); //修改列表元素 l.clear(); l.addAll(l1); l.set(0, new Manx()); System.out.println("[10]: " + l); //查看列表是否为空 System.out.println("[11]: isEmpty " + l.isEmpty()); //根据索引返回元素 Pet p = l.get(2); System.out.println("[12]: " + p); //获得元素索引 System.out.println("[13]: indexOf " + l.indexOf(p)); //判断是否包含 System.out.println("[14]: " + l.contains(p)); //返回一个含有列表所有元素的数组 Object[] o = l.toArray(); System.out.println("[15]: " + o[3]); } }
2.LinkedList
特点:①由链表实现善于增删数据
②实现了栈、队列、双端队列的方法,可直接作为栈、队列、双端队列使用
实例一:Stack的基本用法
import typeinfo.pets.*; import java.util.*; public class StackLinkedList { public static void main(String[] args) { // TODO Auto-generated method stub LinkedList<Pet> stack = new LinkedList<Pet>(Pets.arrayList(6)); System.out.println("[1]: " + stack); Rat r = new Rat(); stack.push(r); System.out.println("[2]: " + stack); stack.pop(); stack.pop(); System.out.println("[3]: " + stack); } }
结果:
实例二:Queue的基本用法
public class QueueLinkedList { public static void printQ(Queue q) { while(q.peek() != null) { System.out.print(q.remove() + " "); } System.out.println(); } public static void main(String[] args) { // TODO Auto-generated method stub Random rand = new Random(); Queue<Integer> queue = new LinkedList<Integer>(); for(int i = 0; i < 8; i++) { queue.offer(rand.nextInt(i + 10)); } printQ(queue); Queue<Character> qc = new LinkedList<Character>(); for(Character c : "haohao".toCharArray()) { qc.offer(c); } printQ(qc); } }
输出:
2 9 6 6 11 13 12 11
h a o h a o
实例三:PriorityQueue的基本用法
按照Integer、Character、String的内建自然顺序排序
import java.util.*; public class PriorityQueueList { public static void main(String[] args) { // TODO Auto-generated method stub PriorityQueue<Integer> pq = new PriorityQueue<Integer>(); Random rand = new Random(); for(int i = 0; i < 10; i++) { pq.offer(rand.nextInt(i + 10)); } QueueLinkedList.printQ(pq); List<Integer> l = Arrays.asList(2,4,3,1,5,10); pq = new PriorityQueue<Integer>(l); QueueLinkedList.printQ(pq); PriorityQueue<Integer> pq1 = new PriorityQueue<Integer>(10, Collections.reverseOrder()); pq1.addAll(l); QueueLinkedList.printQ(pq1); } }
二、Set
共同特点:①不保存重复元素
②善于查找,基于对象值
1.HashSet
特点:①基于Hash表散列函数实现,存储元素不保证有序
②专门对快速查找进行了优化
2.LinkedHashSet
特点:①基于Hash表散列函数实现,看起来却像使用链表维护
②是HashSet的子类
3.TreeSet
特点:①基于红黑树实现,会对存储元素进行排序
import java.util.*; public class SetMethod { public static void main(String[] args) { // TODO Auto-generated method stub Set<Integer> s = new HashSet<Integer>(Arrays.asList(3,1,2,5,6,7,4)); System.out.println("[1]: " + s); s.add(8); System.out.println("[2]: " + s); Set<Integer> s1 = new HashSet<Integer>(Arrays.asList(5,4,3,2,1)); System.out.println("[3]: " + s1); System.out.println("[4]: " + s.containsAll(s1)); System.out.println("[5]: " + Arrays.asList(3,1,2,5,6,7,4)); } }
结果:
这个结果咋是有序的嘞,正所谓“悬之又悬,妙不可言”,有点复杂 哈哈 以后再说。
三、Map
Map和Set情况差不多,不过Map是基于键值对的
实例:
import java.util.*; import typeinfo.pets.*; public class MapBase { public static void main(String[] args) { // TODO Auto-generated method stub Map<String, Pet> m = new HashMap<String, Pet>(); m.put("My Rat", new Rat("honghong")); m.put("My ManX", new Manx()); m.put("My Pug", new Pug()); System.out.println(m); Pet p = m.get("My Rat"); System.out.println(p); System.out.println(m.containsKey("My Pug")); System.out.println(m.containsValue(p)); } }
结果: