- 浏览: 403574 次
- 性别:
- 来自: 秦皇岛
最新评论
-
prayjourney:
了解了,讲的不错
DataInputStream和DataOutputStream类 -
niunianss:
将字节退回的时候,需要添加判断,最后一个字符是英文时,实际数组 ...
PushbackInputStream -
cctt_1:
不要误人子弟,那根本就不是 解释器模式!!!那是Composi ...
Interpreter(解释器)模式 -
java-大神:
[i][i]引用引用引用引用[/img][/img][/img ...
BufferedReader和BufferedWriter -
百合不是茶:
你的程序在文件输入输出流中传入agrs[0]时,会报错越界 ...
DataInputStream和DataOutputStream类
一 Collection类:
Collection结构可持有各自独立的对象。在J2SE中,Collection包括了List与Set,List是实现java.util.List接口的相关类,可依对象被放置至容器中的顺序来排列对象。Set是实现java.util.Set接口的相关类,不接受重复的对象,并可拥有一套排序规则。
1. List接口简介:
(1) List接口是java.util.Colleciton接口的子接口,而Collection接口则是java.lang.Iterable的子接口。Iterable接口要求实现一个iterator()方法。
package java.lang; import java.util.Iterator; public interface Iterable<T> { Iterator<T> iterator(); }
从J2SE 5.0开始增加了泛型设计的新功能,所以像Iterable、Collection相关接口与其实现类,都使用泛型的功能重新改写了。
(2) Iterable接口要求实现它的类返回一个实现java.util.Iterator接口的对象,事实上在J2SE的API中找不到任何实现Iterator的类,因为Iterator会根据实际的容器数据结构来迭代元素,而容器的数据结构实现方式对外界是隐藏的,使用者不用知道这个结构,只需要知道Iterator的实现方法,就可以取出元素。Iterator接口的定义如下:
package java.util; public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }
Collection接口继承了Iterator接口,定义了加入元素、删除元素、元素长度等方法。如下代码(从JDK安装目录下src.zip中找出来的。)
package java.util; public interface Collection<E> extends Iterable<E> { int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); int hashCode(); }
Collection在删除元素及取得元素上的定义比较通用,List接口则又增加了根据索引取得对象的方法,这说明了List数据结构的特性,每个加入List中的元素是循序加入的,并可指定索引来存取元素。
package java.util; public interface List<E> extends Collection<E> { int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean addAll(int index, Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); int hashCode(); E get(int index); E set(int index, E element); void add(int index, E element); E remove(int index); int indexOf(Object o); int lastIndexOf(Object o); ListIterator<E> listIterator(); ListIterator<E> listIterator(int index); List<E> subList(int fromIndex, int toIndex); }
List可以使用数组(Array)或是链接串行(Linked List)来实现这个特性,前者在J2SE中的实现就是java.util.ArrayList,后者就是java.util.LinkedList。对于循序加入与存取,使用ArrayList的效率比较好,对于经常变动元素排列顺序的需求,使用LinkedList会比较好。
(3)ArrayList: ArrayList实现了List接口,使用数组结构实现List数据结构。数组的特性是可以利用索引来快速指定对象的位置,所以对于快速的随机取得对象来说,使用ArrayList可以得到较好的效率。但由于使用数组实现,若要从中间作删除或插入对象的动作,会需要移动后段的数组元素以重新调整索引顺序,所以速度上会慢得多。下面是一个利用ArrayList的例子:
package onlyfun.caterpillar; import java.util.*; public class ArrayListDemo { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); List<String> list = new ArrayList<String>(); System.out.println("输入名称(使用quit结束)"); while(true) { System.out.print("# "); String input = scanner.next(); if(input.equals("quit")) break; list.add(input); } System.out.print("显示输入"); for(int i=0;i<list.size();i++) { System.out.print(list.get(i)+" "); } System.out.println(); } };
在J2SE 5.0之后新增了泛型功能,使用对象容器时可以声称将存储的对象类型。这样,对象在存入容器时会被限定为所声称的类型。编译器在编译时将协助进行类型检查,而取出对象时也不至于失去原来的类型信息,这可以避免类型转换时的问题。使用toArray()方法可以将ArrayList中的对象转换为对象数组,size()方法可以返回当前的ArrayList长度,add()方法可以将一个对象加入ArrayList中,get()方法可以返回指定索引处的对象。但如果您的目的是要循序取出容器中的所有对象,则建议使用Iterator。Iterator类的使用是Iterator模式的一个实例。下面使用Iterator的功能改写上面的程序:
package onlyfun.caterpillar; import java.util.*; public class IteratorDemo { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); List<String> list = new ArrayList<String>(); System.out.println("输入名称(使用quit结束)"); while(true) { System.out.print("# "); String input = scanner.next(); if(input.equals("quit")) break; list.add(input); } System.out.print("显示输入"); //使用Iterator取得元素 Iterator iterator = list.iterator(); while(iterator.hasNext()) { System.out.print(iterator.next() + " "); } System.out.println(); } };
iterator()方法会返回一个Iterator对象,这个对象提供遍访容器元素的方法。hasNext()方法测试Iterator中是否还有对象,如果有,可以使用next()方法取出。J2SE的API中没有实现Iterator的类,本例中Iterator的实例是在ArrayList中根据数组的数据结构而实现的。
(4) LinkedList:List默认是以对象加入(Add)容器的顺序来排列它们,List上的add()方法也可以指定位置插入对象。如果对象加入之后是为了取出,而不会常作删除或插入的动作,则用ArrayList效率会比较好。如果经常从容器中作插入或删除的动作,则用java.util.LinkedList会获得较好的效率。由于使用LinkedList使用链表,在进行插入或删除动作时有较好的效果,适合用来实现堆栈(Stack)与队列(Queue)。下面是利用LinkedList实现的一个先进先出的队列实例,当然也可以利用LinkedList来实现一个先进后出的堆栈类。
package onlyfun.caterpillar; import java.util.*; public class StringQueue { private LinkedList<String> linkedList; public StringQueue() { linkedList = new LinkedList<String>(); } public void put(String name) { linkedList.addFirst(name); } public String get() { return linkedList.removeLast(); } public boolean isEmpty() { return linkedList.isEmpty(); } }
使用StringQueue类的示例如下:
package onlyfun.caterpillar; import java.util.Scanner; public class StringQueueDemo { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); StringQueue queue = new StringQueue(); System.out.println("输入名称(使用quit结束)"); while(true) { System.out.print("# "); String input = scanner.next(); if(input.equals("quit")) { break; } queue.put(input); } System.out.print("显示输入: "); while(!queue.isEmpty()) { System.out.print(queue.get()+" "); } System.out.println(); } }
事实上,如果要使用队列的功能,也不用亲自实现。在J2SE 5.0中,LinkedList也实现了java.util.Queue接口,所以可以直接实现LinkedList的实例进行队列实现。如下:
pakcage onlyfun.caterpillar; import java.util.*; public class QueueDemo { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Queue<String> queue = new LinkedList<String>(); System.out.println("输入名称,使用quit结束"); while(true) { System.out.print("# "); String input = scanner.next(); if(input.equals("quit")) break; //加入元素到队列中 queue.offer(input); } System.out.print("显示输入"); String element = null; //poll():取得并删除队列中的元素 //队列为空时就返回null while((element=queue.poll())!=null) { System.out.print(element+" "); } System.out.println(); } }
Queue有五个必须要实现的方法,范例中示范了offer()与poll()的实现。另外,还有element()可取得但不得删除队列第一个组件,队列为空时抛出意外。remove()取得并删除队列第一个组件。peek()可取得但不删除队列的第一个组件。
2. HashSet:java.util.HashSet实现了java.util.Set接口,Set接口一样继承了Collection接口。List容器中的对象允许重复,但Set容器中的对象不许重复,都是唯一的。加入Set容器中的对象都必须重新定义equals()方法,用作Set中对象的唯一识别。Set容器有自己的一套排序规则。
HashSet的排序规则是利用哈希法(Hash),所以加入HashSet容器的对象还必须重新定义hashCode()方法。HashSet根据哈希码来确定对象在容器中存储的位置,也可以根据哈希码来快速地找到容器中的对象。在定义类时最好总是重新定义equals()与hashCode()方法,以符合Java的设计规范。下面程序片段展示了如何使用HashSet。
package ysu.hxy; import java.util.*; public class HashSetDemo { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("sssssssss"); set.add("ttttttt"); set.add("gggggggg"); //故意加入重复的对象 set.add("gggggggg"); //使用Iterator显示对象 Iterator iterator = set.iterator(); while(iterator.hasNext()) System.out.print(iterator.next()+ " "); System.out.println(); set.remove("gggggggg"); for(String name:set) { System.out.print(name+" "); } System.out.println(); } }
虽然故意重复加入了gggggggg字符串,但HashSet中仍只有一个gggggggg字符串对象,这是Set的特性。迭代HashSet中所有的值时,其顺序与加入容器的顺序是不一样的,迭代所有值时的顺序是HashSet排序后的顺序。如果想要在显示时按加入的顺序显示,则可以使用java.util.LinkedHashSet。LinkedHashSet是HashSet的子类,它在内部实现时使用哈希码进行排序,然而允许在迭代时行为像LinkedList.
3.TreeSet:TreeSet实现Set接口与java.util.SortedSet接口,SortedSet提供相关的方法让您有序地取出对应位置的对象,像first()、last()等方法。TreeSet是J2SE中唯一实现SortedSet接口的类,它使用红黑树结构来对加入的对象进行排序。
package ysu.hxy; import java.util.*; public class TreeSetDemo { public static void main(String[] args) { Set<String> set = new TreeSet<String>(); set.add("justin"); set.add("caterpillar"); set.add("momor"); for(String name: set) System.out.print(name+ " "); System.out.println(); } }
输出结果是:caterpillar justin momor。TreeSet默认的排序是依字典顺序来进行的。如果对对象有自己的一套排列顺序,要定义一个实现java.util.Comparator接口的对象,要实现接口中的compare()方法, compare()方法必须返回整数值。如果对象顺序相同则返回0,返回正整数表示compare()方法中传入的第一个对象大于第二个对象,反之则返回负整数。举个实际例子,假设想要改变TreeSet依字典顺序排列加入的对象为相反的顺序,可以如下自定义一个实现Comparator接口的类。
package ysu.hxy; import java.util.Comparator; public class CustomComparator<T> implements Comparator<T> { public int compare(T o1,T o2) { if(((T)o1).equals(o2)) return 0; return ((Comparable<T>)o1).compareTo((T)o2)*-1; } }
在此自定义的Comparator中,两个对象顺序相同会返回0,而为了便于比较,Comparator传入的对象必须实现Comparable接口(例如String对象就有实现Comparable接口)。乘以-1表示以字典顺序反序进行排列。用以下代码来使用自定义的排序方式,在建构TreeSet实例时一并指定自定义的Comparator。
package ysu.hxy; import java.util.*; public class TreeSetDemo2 { public static void main(String[] args) { //自定义Comparator Comparator<String> comparator = new CustomComparator<String>(); Set<String> set = new TreeSet<String>(comparator); set.add("justin"); set.add("caterpillar"); set.add("momor"); for(String name:set) System.out.print(name + " "); System.out.println(); } }
输出结果与上面的输出结果正好相反:momor justin caterpillar。
4. EnumSet:java.util.EnumSet是J2SE 5.0后新加入的新类,可在协助建立枚举值的集合。EnumSet提供了一系列的静态方法,可以让您指定不同的集合建立方式。如下简单示例:
package ysu.hxy; import java.util.*; //定义枚举类型 enum FontConstant{Plain,Bold,Italic}; public class EnumSetDemo { public static void main(String[] args) { //建立枚举值集合 EnumSet<FontConstant> enumSet = EnumSet.of(FontConstant.Plain,FontConstant.Bold); //显示集合内容 showEnumSet(enumSet); //显示补集合内容 showEnumSet(EnumSet.complementOf(enumSet)); } public static void showEnumSet(EnumSet<FontConstant> enumSet) { for(FontConstant constant:enumSet) System.out.println(constant); System.out.println(); } }
可以指定枚举值来加入EnumSet中,使用of()方法会返回一个体EnumSet实例,其中包括所指定的枚举值,也可以使用complementOf()指定一个EnumSet的互补集。当然也可以先建立一个空的EnumSet,然后再逐个加入枚举值,如下程序片段:
package ysu.hxy; import java.util.*; enum FontConstant { Plain, Bold, Italic} public class EnumSetDemo2 { public static void main(String[] args) { //建立EnumSet实例,初始内容为空 EnumSet<FontConstant> enumSet = EnumSet.noneOf(FontConstant.class); //加入枚举 enumSet.add(FontConstant.Bold); enumSet.add(FontConstant.Italic); showEnumSet(enumSet); } public static void showEnumSet(EnumSet<FontConstant> enumSet) { for(FontConstant constant : enumSet) { System.out.println(constant); } System.out.println(); } }
二 Map类:
实现java.util.Map接口的对象会将键(Key)映射至值(Value),值指的是存入Map容器的对象。在将对象存入Map对象时,需要同时给定一个键,要取回对象时可以指定键,这样就可以取得与键对应的对象值。Map中的每一个键都是唯一的,不能有重复的键,Map拥有自己的排序机制。
1. HashMap:java.util.HashMap实现了Map接口,HashMap在内部实现使用哈希法,让您在很短的时间内可以寻得键-值匹配。如下代码:
package ysu.hxy; import java.util.*; public class HashMapDemo { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); String key1 = "caterpillar"; String key2 = "justin"; //Map的put()方法存入时,必须同时指定键和值 map.put(key1,"caterpillar的信息"); map.put(key2,"justin的信息"); //需要取回对象时,使用get()方法并指定键,返回的会是对应于键的值 System.out.println(map.get(key1)); System.out.println(map.get(key2)); } }
程序执行结果:caterpillar的信息
justin的信息
可以使用values()方法返回一个实现Collection的对象,其中包括所有的值对象。如果需要一次迭代Map中所有的对象,这会很有用。如下:
package ysu.hxy; import java.util.*; public class HashMapDemo2 { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); map.put("momor","momor的信息"); map.put("justin","justin的信息"); map.put("caterpillar","caterpillar的信息"); Collection collection = map.values(); Iterator iterator = collection.iterator(); while(iterator.hasNext()) System.out.println(iterator.next()); System.out.println(); //用增强的for循环也可以 for(String value:map.values()) System.out.println(value); } }
运行结果:justin的信息
momor的信息
caterpillar的信息
justin的信息
momor的信息
caterpillar的信息
如果想按插入的顺序来排列迭代的所有对象,则可以使用java.util.LinkedHashMap,它是HashMap的子类,在使用values()所返回的Collection对象,其内含对象之顺序即为当初加入对象之顺序。可以将上面代码中的new HashMap<String,String>()改为new LinkedHashMap<String,String>()进行测试。
2. TreeMap:java.util.TreeMap实现Map接口与java.util.SortedMap接口,SortedMap接口提供的方法让您有序地取出对应位置的对象。像firstKey(),lastKey()等方法。TreeMap是J2SE中唯一实现SortedMap接口的类,它使用红黑树结构来对加入的对象进行排序(默认是依据键值的字典顺序排序)。可以直接用TreeSet的CustomComparator类来自定义排序规则。用以下代码来测试:
package ysu.hxy; import java.util.*; public class TreeMapDemo2 { public static void main(String[] args) { CustomComparator<String> comparator = new CustomComparator<String>(); Map<String,String> map = new TreeMap<String,String>(comparator); map.put("justin","justin的信息"); map.put("momor","momor的信息"); map.put("caterpillar","caterpillar的信息"); for(String value:map.values()) System.out.println(value); } }
3.EnumMap类:java.util.EnumMap类是专为枚举类设计的Map类,方便您使用枚举类及Map对象,如下例:
package ysu.hxy; import java.util.*; enum Action{TURN_LEFT,TURN_RIGHT,SHOOT} public class EnumMapDemo { public static void main(String[] args) { Map<Action,String> map = new EnumMap<Action,String>(Action.class); map.put(Action.TURN_LEFT,"左转"); map.put(Action.TURN_RIGHT,"右转"); map.put(Action.SHOOT,"射击"); for(Action action:Action.values()) { //以Action枚举为键取出值 System.out.println(map.get(action)); } } }
运行结果: 左转
右转
射击
与单纯的使用HashMap的差别是,EnumMap将根据枚举的顺序来维护对象的排列顺序,如在紧挨着的上段代码中,如果将三个map.put();调换顺序,最终输出的结果都是依据枚举的顺序来排列的。
发表评论
-
内部类总结
2009-11-27 14:28 1176一、方法及作用域内的内部类:1.在一个方法内定义的类2.在一个 ... -
finalize()方法终结条件验证 示例代码
2009-09-20 09:23 1294package Initialization; clas ... -
Proxy(代理)模式二
2009-05-15 21:16 15152. 重新思考图像代理: 现在需要思考设计模式是否 ... -
Junit简介
2009-04-08 17:46 15501. 单元测试(Unit Test) 一个单元(Un ... -
Ant简介
2009-04-08 13:10 17381. Ant可以自动完成的任务: (1)编译Java源代 ... -
专题制作--文字编辑器(文字编辑与保存)
2009-04-08 10:43 21481. 文字编辑与保存: (1). 打开文件的处理流 ... -
专题制作--文字编辑器(逻辑实现部分)
2009-04-07 22:35 18531. 事件处理: 在Java中事件以具体的对象来表 ... -
专题制作--文字编辑器(接口部分)
2009-04-07 20:28 21011. Swing入门: 若要使用J2SE来开发窗口应用 ... -
信息绑定(国际化处理)
2009-04-07 20:02 15281. 程序中的一些文字信息可以将之定义在一个属性文件中,而不定 ... -
日志(Logging)
2009-04-07 16:14 16181. 日志(Logging) 程序不免会出现错误,当 ... -
Java中的日期和时间
2009-04-07 11:26 19081. 使用Date: 使用System.cu ... -
meta-annotation
2009-04-07 09:23 30151. 所谓meta-annotation就是Annotati ... -
Annotion
2009-04-06 23:05 16331. Annotation对程序运行没有影响,它的目的在于对编 ... -
使用反射生成与操作对象(二)
2009-04-06 17:04 17211. 修改成员值: 尽管直接存取类的域成员是不被鼓励的 ... -
使用反射生成与操作对象(一)
2009-04-06 15:16 20481. 使用反射机制,可以在运行时期动态加载类并生成对象,操作对 ... -
Java中的反射(二)
2009-04-06 10:42 19751. 当在命令行模式下执行java XXX.class 指令后 ... -
Java中的反射(一)
2009-04-06 09:43 12881. Java提供的反射机制允许您在运行时动态加载类、查看类信 ... -
容器类的线程安全及ThreadLocal类
2009-04-05 21:28 30141. 容器类默认没有考虑 ... -
wait()和notify()
2009-04-05 19:06 13201. wait()、notify()、notifyAll() ... -
Java线程之同步化(Synchronized)主题
2009-04-05 16:44 26721. 如果一个对象所持有的数据可以被多线程同时共享存取,必须 ...
相关推荐
该PPT详尽地描述了Java对象容器的属性以及如何使用,不用多说,Java对象容器如ArrayList,List,Set,HaspMap等都是极为重要的容器类,学好这个无疑把握了Java的灵魂所在
归纳了java中常用容器包括List、set、map等
。。。
Java对象的容纳 一. 数组二. 容器Java对象的容纳 一. 数组二. 容器
NULL 博文链接:https://howarezhao.iteye.com/blog/1323147
java容器简介 Array对象 List Set 迭代器Iterator
java 容器类 集合类 Collection 你懂了吗
中山大学研究生学院java讲义之(对象容器)
Java的容器类有两种基本类型:Collection和Map,区别在于容器中每个位置保存的元素个数。Collection每个位置只能保存一个元素,Map保存的是键值对。 2、迭代器,是一个对象,它的工作是遍历并选择序列中的对象,...
Java程序.............................................................................................6 1.3.1 Java程序的结构 ...........................................................................
java实现连接池 没有容器,存java面向对象设计的一个连接池的例子 面试中经常问道的哦
第13章 容器和泛型.pptx 第14章 流与文件(1).pptx 第14章 流与文件(2).pptx 第15章 网络编程.pptx 第1章 Java概述.pptx 第2章 Java基础.pptx 第3章 数组.pptx 第4章 类和对象(1).pptx 第4章 类和对象(2)....
第2章 Java对象持久化技术概述 2.1 直接通过JDBC API来持久化实体域对象 2.2 ORM简介 2.2.1 对象-关系映射的概念 2.2.2 ORM中间件的基本使用方法 2.2.3 常用的ORM中间件 2.3 实体域对象的其他持久化模式...
Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,意味着可以在不同的操作系统上运行。Java具有简单、可移植、高性能和安全性等特点,因此被广泛应用于各种领域。 Java编程...
在Java中,容器(Container)指的是用于存储和管理对象的数据结构。Java容器提供了一种统一的方式来组织和管理多个对象,使得开发者能够更加方便地对这些对象进行操作和处理。 Java容器主要分为两大类:Collection ...
开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。开源地址:https://github.com/eclipse/jetty.project特点:Jetty PoweredJetty PoweredFull-...
Collection 表示一组对象,它是集中,收集的意思,就是把一些数据收集起来 Collection接口的两个子接口: Set中的数据没有顺序,不可重复。 List中的数据有顺序,可重复。
Java集合容器面试题(2023最新版)-重点 **集合框架:**用于存储数据的容器。 集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。 任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合...
// java中对象容器主要有Set,List和Map三个接口类。 // 迭代器(Iterator)模式,又叫做游标(Cursor)模式。 // GOF给出的定义为:提供一种方法访问一个容器(container)对象中的各个元素, // 而又不需暴露该...