首页 > 代码库 > Java编程思想(八) —— 持有对象(1)
Java编程思想(八) —— 持有对象(1)
书中的原标题是——holding your object,把握你的对象,译者翻译成持有对象。这是用的最多的类之一。
作者说的,如果一个程序包含固定数量的且其生命周期都是已知的对象,那么这是一个非常简单的程序。确实,如果数组大小已知,那么就很简单了。
除了数组,Java提供了容器类来holding object。
1)泛型和类型安全的容器
ArrayList,可以自动扩充大小的数组,add插入对象,get访问对象,size查看对象数目。
class Apple{} public class Box { public static void main(String[] args) { ArrayList<Apple> a = new ArrayList<Apple>(); a.add(new Apple()); } }
泛型(就是跟在ArrayList后面的那个尖括号指明Apple类型的标识)的添加可以在编译期间防止将错误类型的对象放进容器中。
同样,容器也可以用foreach语法。
2)概念
容器类作用是保存对象。分为两个:
一、Collection,List顺序保存元素,Set不能有重复元素,Queue按照排队来。
二、Map,键值对,通过键找值或者被称为字典。
对了,写了这么多篇,忘记说一件重要的事情了,懂得查API文档,最好看英文版。Collection是什么,类还是接口,一查就知道了。
public interface List<E> extends Collection<E> public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
这样的关系就出来了。
3)添加一组元素
public class AddGroup { public static void main(String[] args) { Collection<Integer> c = new ArrayList<Integer>(Arrays.asList(1,2,3,4)); Integer[] group = {5,6,7,8 }; c.addAll(Arrays.asList(group)); System.out.println(c); Collections.addAll(c, 9,0); System.out.println(c); } } //[1, 2, 3, 4, 5, 6, 7, 8] //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
Collections.addAll,Adds all of the specified elements to the specified collection.
将其他元素添加到Collection c中,而Collection.addAll是添加一组元素。
4)容器的打印
其实上面的代码已经看出,具体的容器已经实现了自己的toString方法。
5)List
List有两种:ArrayList,随机访问元素快,中间插入和删除操作慢。
LinkedList,随机访问慢,但是中间插入和删除快,类似链表。
List常用方法:
class Member{ int age; Member(int i){ age = i; } public String toString(){ return "member"+age; } } public class ListMethod { public static void main(String[] args) { List<Member> members = new ArrayList<Member>(); Member member1 = new Member(1); //添加元素 members.add(member1); //判断容器是否为空 System.out.println(members.isEmpty()); //判断容器是否包含该元素 System.out.println(members.contains(member1)); //显示索引 System.out.println(members.indexOf(member1)); //移除元素 members.remove(member1); System.out.println(members); Member member2 = new Member(2); Member member3 = new Member(3); Member member4 = new Member(4); members.add(member2); members.add(member3); members.add(member4); //类似subString,从索引0开始截取到1,包含0和1 System.out.println(members.subList(0, 2)); //移除 不同于remove //removeAll(Collection<?> c) //remove(int index) remove(Object o) members.removeAll(members); System.out.println(members); } }
6)迭代器
在没用迭代器之前,遍历是这样写的:
for(int i = 0; i < newList.size(); i++){ System.out.println(newList.get(i)); }
而迭代器被称为轻量级对象,创建的代价小。
Iterator<Member> iterator = members.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); }
next移动下一个元素,但是拿到的当前元素。hasNext检查是否还有元素,Iteratorf容器返回一个Iterator。
7)ListIterator
这个之前没听过,Iterator只能向前移动,ListIterator可以双向移动。
ListIterator<Member> iterator = members.listIterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } while(iterator.hasPrevious()){ System.out.println(iterator.previous()); }
向前输出,向后输出。
8)LinkedList
插入移除高效。
方法很容易理解,属于自解释型的方法名。
public class TestLinkedList { public static void main(String[] args) { LinkedList<Member> members = new LinkedList<Member>(); Member member1 = new Member(1); Member member2 = new Member(2); Member member3 = new Member(3); members.add(member1); members.add(member2); members.add(member3); //返回列表头 System.out.println(members.peek()); //移除并返回列表头 System.out.println(members.removeFirst()); System.out.println(members); //返回并移除表头 System.out.println(members.poll()); System.out.println(members); //removelast 移除最后一个 members.add(member1); members.add(member2); System.out.println(members.removeLast()); System.out.println(members); //addLast和add一样 都是往列表尾插入元素 addFirst自然就是表头 members.add(member2); members.addFirst(member2); members.addLast(member2); System.out.println(members); } }
9)Stack
栈,后进先出,
其实用LinkedList就可以实现栈的功能了,push,进的时候,只需要addFirst,pop,出的时候,只需要removeFirst,这样就达到了先进后出
10)Set
Set,元素不重复。
Set与Collection有完全一样的接口,但是不同List,虽然Set就是Collection,但是行为不同,这就是多态和继承的应用了。
public class TestSet { public static void main(String[] args) { Set<Integer> set = new HashSet<Integer>(); Random r = new Random(400); for(int i = 0;i<20;i++){ set.add(r.nextInt(300)); } System.out.println(set); } }
HashSet,没有重复元素,顺序也无规律,其实是使用了散列,以后会提到。
如果:
Set<Integer> set = new TreeSet<Integer>();会发现是有序的,TreeSet将元素存储在了红黑树里面。
书中有一处错误:LinkedHashSet写成LinkedHashList了,它也使用散列,但是看起来使用了链表维护元素插入顺序。
持有对象这一章的内容不会难,因为平时用的太多,就是内容多,接下来下一篇会写Map,Queue和总结这一章的东西。
------------------------- 独在异乡为异客,每逢中秋倍思亲-----------------------------
Java编程思想(八) —— 持有对象(1)