1.ArrayList
ArrayList类别实作了List接口,List接口是Collection接口的子接口,主要增加了根据索引取得对象的方法。ArrayList使用数组实作List接口,所以对于快速的随机取得对象来说,使用ArrayList可以得到较好的效能,不过在移除对象或插入对象时,ArrayList就比较慢(使用 LinkedList 在这方面就好的多)。来看看一个ArrayList的范例:
ArrayListDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class ArrayListDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List list = new ArrayList();
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 之后新增了泛型(Generic)的功能,使用对象容器时建议容器中将储存的对象型态,如此您的对象在存入容器会被限定为您所宣告的型态,而取出时,也不至于失去原来的型态信息,可以避免型态转换时的问题。使用add()方法可以将一个对象加入ArrayList中,使用size()方法可以传回目前的ArrayList的长度,使用get()可以传回指定索引处的对象,使用toArray()可以将ArrayList中的对象转换为对象数组。以下是执行结果:
输入名称(quit结束)
# Justin
# caterpillar
# momor
# quit
显示输入: Justin caterpillar momor?
您可以使用get()方法指定索引值取出对象,然而如果您的目的是要循序取出容器中所有的对象,则您可以使用Iterator类,Iterator类实作 Iterator 模式,实际来看个例子:
ArrayListDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class ArrayListDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List list = new ArrayList();
System.out.println("输入名称(quit结束)");
while(true) {
System.out.print("# ");
String input = scanner.next();
if(input.equals("quit"))
break;
list.add(input);
}
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
iterator()方法会传回一个Iterator对象,这个对象提供的遍访的方法,hasNext()方法测试Iterator中是否还有对象,如果 有的话,可以使用next()取出。事实上,在J2SE 5.0您也不必须使用iterator()了,使用增强的for循环可以直接遍访List的所有元素,例如:
ArrayListDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class ArrayListDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List list = new ArrayList();
System.out.println("输入名称(quit结束)");
while(true) {
System.out.print("# ");
String input = scanner.next();
if(input.equals("quit"))
break;
list.add(input);
}
for(String s : list) {
System.out.print(s + " ");
}
System.out.println();
}
}
2.LinkedList
List类是以对象加入(add)容器的顺序来排列它们,如果您的对象加入之后大都是为了取出,而不会常作移除或插入(Insert)的动作,则使用ArrayList,如果您会经常从容器中作移除或插入对象的动作,则使用LinkedList会获得较好的效能。LinkedList实作了List接口,并增加了一些移除与插入对象的特定方法,像是addFirst()、addLast()、 getFirst()、getLast()、removeFirst( )、removeLast()等等,由于在插入与移除时有较好的效能,适合拿来实作堆栈(Stack)与队列(Queue)。以下实作一个简单的FILO(First-In, Last-Out)堆栈,可以存入字符串:
StringStack.java
package onlyfun.caterpillar;
import java.util.*;
public class StringStack {
private LinkedList linkedList;
public StringStack() {
linkedList = new LinkedList();
}
public void push(String name) {
linkedList.addFirst(name);
}
public String top() {
return linkedList.getFirst();
}
public String pop() {
return linkedList.removeFirst();
}
public boolean isEmpty() {
return linkedList.isEmpty();
}
}
而对于FIFO(First-In, First-Out)的队列,我们也可以使用LinkedList来实作:
StringQueue.java
package onlyfun.caterpillar;
import java.util.*;
public class StringQueue {
private LinkedList linkedList;
public StringQueue() {
linkedList = new LinkedList();
}
public void put(String name) {
linkedList.addFirst(name);
}
public String get() {
return linkedList.removeLast();
}
public boolean isEmpty() {
return linkedList.isEmpty();
}
}
事实上,如果您要使用队列的功能,您也不用亲自实作,在J2SE 5.0中,LinkedList也实作了新加入的java.util.Queue接口,这个接口有五个必须实作的方法:
element()
取得但不移除队列第一个组件,队列为空时会丢出例外
offer()
加入一个元素至队列中
peek()
取得但不移除队列第一个组件
poll()
取得并移去队列第一个组件,队列为空时传回null
remove()
取得并移除队列第一个组件
要使用队列的功能,您只要类似这样的宣告:
Queue<String> queue = new LinkedList<String>();
3.HashSet
HashSet实作Set接口,Set接口继承Collection接口,Set容器中的对象都是唯一的,加入 Set容器中的对象都必须重新定义equals()方法,作为唯一性的识别,Set容器有自己的一套排序规则。HashSet的排序规则是利用Hash Table,所以加入HashSet容器的对象还必须重新定义hashCode()方法,利用Hash的方式,可以让您快速的找到容器中的对象,在比较两个加入Set容器中的对象是否相同时,会先比较hashCode()方法传回的值是否相同,如果相同,则再使用equals()方法比较,如果两者都相同,则视为相同的对象。事实上,在撰写新的类别时,最好总是重新定义equals()与hashCode()方法,以符合Java的设计规范,您可以参考 Object 类别 中的介绍了解如何重新定义equals()与hashCode()。来看一个例子:
HashSetDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class HashSetDemo {
public static void main(String[] args) {
Set set = new HashSet();
set.add("caterpillar");
set.add("justin");
set.add("momor");
set.add("justin");
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
执行结果:
momor justin caterpillar
如上所示的,即使重复加入了"justin"字符串,HashSet中仍只有一个"justin"字符串对象,另一个要注意的是,选代所有的值时,其顺序 与您加入的顺序是不一样的,选代所有值时的顺序是HashSet排序过后的顺序。LinkedHashSet是HashSet的子类,它在内部实作使用Hash Code进行排序,然而允许您在列举时行为像是LinkedList,简单的改写上面的程序即可了解:
LinkedHashSetDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class LinkedHashSetDemo {
public static void main(String[] args) {
Set set = new LinkedHashSet();
set.add("caterpillar");
set.add("justin");
set.add("momor");
set.add("justin");
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
执行结果:
caterpillar justin momor
可以在执行结果中看到的,选代时的顺序正是您加入值的顺序。
4.TreeSet
TreeSet实作Set接口与SortedSet接口,提供相关的方法让您有序的取出对应位置的对象,像是 first()、last()等方法,TreeSet是J2SE中唯一实作SortedSet接口的类别,它使用红黑树结构来对加入的对象进行排序。看个简单的例子:
TreeSetDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class TreeSetDemo {
public static void main(String[] args) {
Set set = new TreeSet();
set.add("justin");
set.add("caterpillar");
set.add("momor");
set.add("justin");
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
由于加入的是String对象,执行结果会自动依字典顺序进行排序的动作:
caterpillar justin momor
依字典顺序排序String对象是TreeSet预设的,如果您对对象有自己的一套排序顺序,您要实作一个 Comparator 对象,您要实作compare()方法,它必须传回整数值,如果对象顺序相同则传回0,传回正整数表示compare()方法的第一个对象大于第二个对象,反之则传回负整数。举个实际的例子,假设您想要改变TreeSet依字典顺序排列加入的对象为相反的顺序:
CustomComparator.java
package onlyfun.caterpillar;
import java.util.Comparator;
public class CustomComparator implements Comparator {
public int compare(T o1, T o2) {
if (((T) o1).equals(o2))
return 0;
return ((Comparable) o1).compareTo((T) o2) * -1;
}
}
在自订的Comparator中,如果两个对象的顺序相同会传回0,这在TreeSet中表示两个对象是同一个对象,TreeSet要求传入的对象必须实 作java.lang.Comparable接口,范例中只是简单的将原来compareTo()传回的值乘以负一,如此在TreeSet中就可以简单的 让排列顺序相反。在建构TreeSet实例时一并指定自订的Comparator,例如:
TreeSetDemo2.java
package onlyfun.caterpillar;
import java.util.*;
public class TreeSetDemo2 {
public static void main(String[] args) {
// 自订Comparator
Comparator comparator =
new CustomComparator();
Set set =
new TreeSet(comparator);
set.add("justin");
set.add("caterpillar");
set.add("momor");
// 使用 enhanced for loop 显示对象
for(String name : set) {
System.out.print(name + " ");
}
System.out.println();
}
}
执行的结果是相反的:
momor justin caterpillar
5.EnumSet
EnumSet的名称说明了其作用,它是在J2SE 5.0后加入的新类别,可以协助您建立列举值的集合,它提供了一系列的静态方法,可以让您指定不同的集合建立方式,例如:
EnumSetDemo.java
package onlyfun.caterpillar;
import java.util.*;
enum FontConstant { Plain, Bold, Italic }
public class EnumSetDemo {
public static void main(String[] args) {
EnumSet enumSet =
EnumSet.of(FontConstant.Plain, FontConstant.Bold);
showEnumSet(enumSet);
showEnumSet(EnumSet.complementOf(enumSet));
}
public static void showEnumSet(
EnumSet enumSet) {
Iterator iterator = enumSet.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
您可以指定列举值来加入EnumSet中,of()方法会返回一个EnumSet的实例,当中包括您所指定的列举值,您也可以使complementOf()指定一个EnumSet的互补集,以下是执行的结果:
Plain Bold
Italic?
EnumSet实作了Set接口,所以您可以使用Set接口的所有方法来测试它所包括的列举值,例如测试一个集合中是否包括 FontConstant.Bold:
if(enumSet.contains(FontConstant.Bold)) {
....
}
您也可以建立一个空的EnumSet,然后自己逐个加入列举值,例如:
EnumSetDemo.java
package onlyfun.caterpillar;
import java.util.*;
enum FontConstant { Plain, Bold, Italic }
public class EnumSetDemo {
public static void main(String[] args) {
EnumSet enumSet =
EnumSet.noneOf(FontConstant.class);
enumSet.add(FontConstant.Bold);
enumSet.add(FontConstant.Italic);
showEnumSet(enumSet);
}
public static void showEnumSet(
EnumSet enumSet) {
Iterator iterator = enumSet.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
执行结果:
Bold Italic
您也可以由一个容器对象中建立EnumSet:
List list = new ArrayList();
list.add(FontConstant.Bold);
list.add(FontConstant.Italic);
showEnumSet(EnumSet.copyOf(list));
更多EnumSet相关的方法,您可以参考 EnumSet 在线API文件。
6.HashMap
HashMap实作Map接口,内部实作使用Hash Table,让您在常数时间内可以寻得key/value对。所谓的key/value对,简单的说,您将Map容器对象当作一个有很多间房间的房子,每个房间的门有一把钥匙,您将对象储存至房间中时,要顺便拥有一把钥匙,下次要取回对象时,就是根据这把钥匙取得。以一个简单的例子来作说明:
HashMapDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class HashMapDemo {
public static void main(String[] args) {
Map< String, String> map =
new HashMap< String, String>();
map.put("caterpillar", "caterpillar's message!!");
map.put("justin", "justin's message!!");
System.out.println(map.get("justin"));
System.out.println(map.get("caterpillar"));
}
}
在宣告Map型态时,您指定了key/value各自的型态,这边都是宣告为String,也就是以String对象作为key对象的型态,而 value也是以String对象作为其型态。使用Map的put()方法将对象存入,必须同时指定key/value,而要取回对象时,则指定key,程序的执行结果如下:
justin's message!!
caterpillar's message!!
HashMap是个被经常使用的对象,您可以参考下面几个例子中HashMap的应用:
Command 模式Thread-Specific Storage 模式控 制器(Servlet)
可以使用values()方法返回一个Collection对象,如果您需要一次选代Map中所有的对象,这会很有用,例如:
HashMapDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class HashMapDemo {
public static void main(String[] args) {
Map< String, String> map =
new HashMap< String, String>();
map.put("justin", "justin's message!!");
map.put("momor", "momor's message!!");
map.put("caterpillar", "caterpillar's message!!");
Collection collection = map.values();
Iterator iterator = collection.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
执行结果:
momor's message!!
justin's message!!
caterpillar's message!!
HashMap使用Hash Table,因而它有自己的排序方式,如果您想要在选代所有的对象时,依照插入的顺序来排序,则可以使用LinkedHashMap,它是HashMap 的子类,使用values()所返回的Collection对象,其内含对象之顺序即为当初您加入对象之顺序,例如:
LinkedHashMapDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class LinkedHashMapDemo {
public static void main(String[] args) {
Map< String, String> map =
new LinkedHashMap< String, String>();
map.put("justin", "justin's message!!");
map.put("momor", "momor's message!!");
map.put("caterpillar", "caterpillar's message!!");
Collection collection = map.values();
Iterator iterator = collection.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
执行结果:
justin's message!!
momor's message!!
caterpillar's message!!
7.TreeMap
TreeMap实作Map接口与SortedMap接口,提供相关的方法让您有序的取出对应位置的对象,像是 firstKey()、lastKey()等方法,TreeMap是J2SE中唯一实作SortedMap接口的类别,它使用红黑树结构来对加入的对象进 行排序。看个简单的例子:
TreeMapDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class TreeMapDemo {
public static void main(String[] args) {
Map< String, String> map =
new TreeMap< String, String>();
map.put("justin", "justin's message!!");
map.put("momor", "momor's message!!");
map.put("caterpillar", "caterpillar's message!!");
Collection collection = map.values();
Iterator iterator = collection.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
由于您加入的是String对象,执行结果会自动依key的字典顺序进行排序的动作:
caterpillar's message!!
justin's message!!
momor's message!!
依字典顺序排序String对象是TreeMap预设的,如果您对对象有自己的一套排序顺序,您要实作一个 Comparator 对象,它有两个必须实作的方法,compare()与equals(),前者必须传回整数值,如果对象顺序相同则传回0,传回正整数表示compare ()方法的第一个对象大于第二个对象,反之则传回负整数,后者则是定义两个对象是否相等。
8、EnumMap
EnumMap是个专为列举型别设计的类别,方便您使用列举型别及Map对象,直接来举个实例:
EnumMapDemo.java
package onlyfun.caterpillar;
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( ) ) {
System.out.println(map.get(action));
}
}
}
执行结果:
向左转
向右转
射击
与单纯的使用HashMap比较起来的差别是,在上面的程序中,EnumMap将根据列举的顺序来维护对象的排列顺序,从下面这个程序可以看个大概:
EnumMapDemo2.java
package onlyfun.caterpillar;
import java.util.*;
enum Action {TURN_LEFT, TURN_RIGHT, SHOOT}
public class EnumMapDemo2 {
public static void main(String[] args) {
Map< Action, String> map =
new EnumMap< Action, String>(Action.class);
map.put(Action.SHOOT, "射击");?
map.put(Action.TURN_RIGHT, "向右转");
map.put(Action.TURN_LEFT, "向左转");
for(String value : map.values( )) {
System.out.println(value);
}
}
}
执行结果:
向左转
向右转
射击
从遍访的结果可以看出,对象的顺序是根据列举顺序来排列的。
转载于:https://www.cnblogs.com/CheeseZH/archive/2012/12/05/2803908.html