Java编程思想: 持有对象
泛型和类型安全的容器
使用Java SE5之前存在的一个问题是: 编译器允许你向容器中插入不正确的类型. 考虑下例:
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import java.util.*;
class Apple {
private static long counter;
private final long id = counter++;
public long id() { return id; }
}
class Orange {}
public class ApplesAndOrangesWithoutGenerics {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
ArrayList apples = new ArrayList();
for (int i = 0; i < 3; i++) {
apples.add(new Apple());
}
apples.add(new Orange());
for (int i = 0; i < apples.size(); i++) {
System.out.println(((Apple)apples.get(i)).id());
}
}
}
1. 由于ArrayList保存的是Object类型, 所以可以存储Apple, Orange类型.
2. 在具体使用时候执行强制类型转换, 由于Orange类型非Apple类型, 所以强制类型转换失败, 导致运行时候抛出异常.
解决方式是使用泛型类型:
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import java.util.*;
class Apple {
private static long counter;
private final long id = counter++;
public long id() { return id; }
}
class Orange {}
public class ApplesAndOrangesWithoutGenerics {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
ArrayList<Apple> apples = new ArrayList();
for (int i = 0; i < 3; i++) {
apples.add(new Apple());
}
// 在编译阶段就直接报错
// apples.add(new Orange());
for(Apple c: apples) {
System.out.println(c.id());
}
}
}
容器的分类
Collection: 一个独立元素的序列, 这些元素都服从一条或多条规则.
List: 顺序存储; Set: 不能重复元素; Queue: 排队规则来确定对象产生的顺序.
ArrayList: 使用数组生成的列表; LinkedList: 使用链表生成的列表.
HashSet: 使用哈希生成的Set集合; TreeSet: 使用红黑树生成的Set集合, 按照比较的顺序升序存储; LinkedHashSet: 按照添加的顺序存储.
PriorityQueue: 优先级队列.
Map: 关联数组, 键值对.
HashMap: 哈希关联数组; TreeMap: 树形关联数组, 使用红黑树生成, 按照比较的顺序升序存储. LinkedHashMap: 按照添加的顺序存储.
Iterator: 迭代器, 标准有next(), hasNext(), remove()三个基本函数.
Collection的基本操作
添加一组元素
Arrays.asList: 接受一个数组或是一个用逗号分割的元素列表, 将其转换为一个List对象.
Collection.addAll: 接受一个数组或者Collection对象.
import java.util.*;
public class Test {
public static void main(String[] args) {
Collection<Integer> collection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Integer[] moreInts = {6, 7, 8, 9};
collection.addAll(Arrays.asList(moreInts));
for (Integer i: collection) {
System.out.print(i + ", ");
}
System.out.println();
}
}
List
size(): 返回其长度
isEmpty(): 判断是否为空
contains(o): 是否包含元素o
toArray: 返回一个Array数组.
add(e)/add(index, e): 增加元素, 或在索引index处增加元素.
remove(index): 在索引index处删除元素.
addAll(Collection): 增加一个Collection.
removeAll(Collection): 删除基于equals()方法的所有Collection中的元素.
hashCode(): 返回其哈希值.
get(index): 获取索引index的值.
indexOf(Object o): 返回其对象o的索引值.
迭代器
迭代器有三个基本的方法:
1. next()获取序列中的下一个元素.
2. 使用hasNext()检查序列中是否还有元素.
3. 使用remove()将迭代器新近返回的元素删除(即调用remove之前必须调用next)
import java.util.*;
public class Test {
public static void print(Object o) {
System.out.print(o + ", ");
}
public static void main(String[] args) {
List<Integer> l = new ArrayList<>(Arrays.asList(1, 2, 3));
Iterator<Integer> iter = l.iterator();
while (iter.hasNext()) {
print(iter.next());
}
}
}
Iterator只能向前移动, 使用ListIterator则可以双向移动.
import java.util.*;
public class Test {
public static void print(Object o) {
System.out.print(o + ", ");
}
public static void main(String[] args) {
List<Integer> l = new ArrayList<>(Arrays.asList(1, 2, 3));
Iterator<Integer> iter = l.iterator();
while (iter.hasNext()) {
print(iter.next());
}
ListIterator<Integer> list = l.listIterator();
while (list.hasNext()) {
print(list.next());
}
while (list.hasPrevious()) {
print(list.previous());
}
}
}
LinkedList
由于LinkedList是链表实现的列表, 所以它可以对列表的头尾进行操作.
例如addFirst()/addLast(), removeFirst()/removeLast(), getFirst()/getLast().
Set
集合主要用于存储不重复的元素, 耶可以使用contains来判断是否存在于集合中, 或者containAll来判断集合A是否存在于集合B中.
HashSet使用散列来生成集合, 而TreeSet使用红黑树来生成有序集合.
import java.util.*;
public class Test {
public static void main(String[] args) {
Set<Integer> s1 = new HashSet<>(Arrays.asList(111, 13, 2));
Set<Integer> s2 = new TreeSet<>(Arrays.asList(1, 3, 2));
System.out.println(s1);
System.out.println(s2);
}
}
Map
import java.util.*;
public class Test {
public static void main(String[] args) {
Map<Integer, Integer> m = new HashMap<>();
m.put(1, 2);
m.put(5, 3);
m.put(3, 0);
m.put(7, 9);
for (Integer i: m.keySet()) {
System.out.println(i + ":" + m.get(i));
}
System.out.println(m.values());
for (Map.Entry entry: m.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
转载于:https://my.oschina.net/voler/blog/716737