转载自:http://peiquan.blog.51cto.com/7518552/1288012
-
Collection — 位于集合框架的顶层,一个Collection代表一组Object,即Collection的元素(Elements)。有的Collection(子类)允许有相同的元素出现而有的就不行,有的Collection(子类)支持排序而有的则不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List、Set和Queue。
-
Set — 扩展了Collection的集合,集合中的元素不可以重复,即任意的两个元素e1和e2都有e1.equals(e2) == false。访问集合中的元素只能根据元素本身来访问。
-
List — 扩展了Collection的集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问。
-
Queue — 提供了队列的实现,除了基本的Collection操作外,队列还提供其他的插入、提取和检查操作。
-
Map — 以Key-value对形式保存元素,访问时只能根据每项元素的key来访问其value。key必须唯一,value的值可以重复。
-
SortedSet — 扩展Set,集合元素按升序排列
-
SortedMap — 扩展Map,以便关键字按升序排列
二、Collection接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
interface
Collection<E>
extends
Iterable<E> {
// 基本方法
int
size();
boolean
isEmpty();
boolean
contains(Object element);
boolean
add(E element);
//可选
boolean
remove(Object element);
//可选
Iterator<E> iterator();
// 批量操作
boolean
containsAll(Collection<?> c);
boolean
addAll(Collection<?
extends
E> c);
//可选
boolean
removeAll(Collection<?> c);
//可选
boolean
retainAll(Collection<?> c);
//可选
void
clear();
//可选
// 数组操作
Object[] toArray();
<T> T[] toArray(T[] a);
}
|
1
2
3
|
for
(Object o : collection){
System.out.println(o);
}
|
1
2
3
4
5
|
public
interface
Iterator<E> {
boolean
hasNext();
//如果仍有元素可以迭代,则返回 true。
E next();
//返回迭代的下一个元素。
void
remove();
//可选操作,移除当前迭代的object
}
|
1
2
3
4
5
|
static
void
filter(Collection<?> c) {
for
(Iterator<?> it = c.iterator(); it.hasNext(); )
if
(!cond(it.next()))
it.remove();
}
|
-
containsAll
— 如果此 collection 包含指定 collection 中的所有元素,则返回 true。 -
addAll
— 将指定collection中的所有元素添加到此collection -
removeAll
— 移除此 collection 中那些也包含在指定 collection 中的所有元素 -
retainAll
— 仅保留此 collection 中那些也包含在指定 collection 的元素,换句话说,移除此 collection 中未包含在指定 collection 中的所有元素。 -
clear
— 移除此 collection 中的所有元素
c.removeAll(Collections.singleton(e));
更具体一点的就是,你可以删除集合c里所有的null元素
c.removeAll(Collections.singleton(null));
附:Collections.singleton是一个静态工厂方法,返回一个只包含指定对象的不可变的set
三、Set接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
interface
Set<E>
extends
Collection<E> {
// 基本方法
int
size();
boolean isEmpty();
boolean contains(
Object
element);
boolean add(E element);
// 可选
boolean remove(
Object
element);
// 可选
Iterator<E> iterator();
// 批量操作
boolean containsAll(Collection<?> c);
boolean addAll(Collection<?
extends
E> c);
// 可选
boolean removeAll(Collection<?> c);
// 可选
boolean retainAll(Collection<?> c);
// 可选
void
clear();
// 可选
// 数组操作
Object
[] toArray();
<T> T[] toArray(T[] a);
}
|
-
HashSet — 以哈希表的形式存储集合元素,它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。可以包含 null 元素。
-
TreeSet — 以红黑树的形式存储集合元素,使用元素的自然顺序对元素进行排序。整体性能比HashSet低
-
LinkedHashSet — 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现,按照元素的插入顺序进行排序。可以包含null元素。
Collection<Type> noDups = new HashSet<Type>(c);
Collection<Type> noDups = new LinkedHashSet<Type>(c); 这个LinkedHashSet的用法,也可以用如下的泛型方法来代替:
1
2
3
|
public
static
<E> Set<E> removeDups(Collection<E> c) {
return
new
LinkedHashSet<E>(c);
}
|
Set的基本操作
1
2
3
4
5
6
7
8
9
10
|
public
class
FindDups {
public
static
void
main(String[] args) {
String[] str = {
"d"
,
"b"
,
"c"
,
"a"
,
"d"
};
Set<String> s =
new
HashSet<String>();
for
(String a : str)
if
(!s.add(a))
System.out.println(
"重复的元素: "
+ a);
System.out.println(s.size() +
" 个不同的元素: "
+ s);
}
}
|
1
2
3
4
5
6
7
8
9
|
// 并集
Set<Type> union =
new
HashSet<Type>(s1);
union.addAll(s2);
// 交集
Set<Type> intersection =
new
HashSet<Type>(s1);
intersection.retainAll(s2);
// 差集
Set<Type> difference =
new
HashSet<Type>(s1);
difference.removeAll(s2);
|
在此,可以回顾一下FindDups,假设你需要找出collection里有哪些元素只出现了一次,哪些元素出现了多次,应该如何实现呢???可以设计两个Set,一个包含了只出现一次的元素,另外一个包含了哪些重复出现的元素,具体的实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
class
FindDups2 {
public
static
void
main(String[] args) {
String[] str = {
"d"
,
"b"
,
"c"
,
"a"
,
"d"
};
Set<String> uniques =
new
HashSet<String>();
Set<String> dups =
new
HashSet<String>();
for
(String a : str){
if
(!uniques.add(a))
dups.add(a);
}
// 移除所有的重复出现的元素
uniques.removeAll(dups);
System.out.println(
"只出现一次的元素: "
+ uniques);
System.out.println(
"重复出现的元素: "
+ dups);
}
}
|
四、List接口
-
索引访问
— 根据元素的索引来操纵元素 -
搜索
— 搜索指定元素并返回其索引 -
Iteration
— 继承了Iterator
,充分利用了List的索引优势 -
截取
— 截取List任意范围的元素
List接口代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
interface
List<E>
extends
Collection<E> {
// 索引访问
E get(
int
index);
E set(
int
index, E element);
//可选
boolean
add(E element);
//可选
void
add(
int
index, E element);
//可选
E remove(
int
index);
//可选
boolean
addAll(
int
index, Collection<?
extends
E> c);
//可选
// 搜索
int
indexOf(Object o);
int
lastIndexOf(Object o);
// 迭代器
ListIterator<E> listIterator();
ListIterator<E> listIterator(
int
index);
// 截取List
List<E> subList(
int
from,
int
to);
}
|
1
2
3
4
5
|
public
static
<E>
void
swap(List<E> a,
int
i,
int
j) {
E temp = a.get(i);
a.set(i, a.get(j));
a.set(j, temp);
}
|
1
2
3
4
|
public
static
void
shuffle(List<?> list, Random rnd) {
for
(
int
i = list.size(); i >
1
; i--)
swap(list, i -
1
, rnd.nextInt(i));
}
|
1
2
3
4
5
6
7
8
9
10
11
|
public
class
Shuffle {
public
static
void
main(String[] args) {
String[] str = {
"a"
,
"b"
,
"c"
,
"d"
,
"e"
,
"f"
};
//可以选择凑够52张牌
List<String> list =
new
ArrayList<String>();
for
(String a : str){
list.add(a);
}
Collections.shuffle(list,
new
Random());
System.out.println(list);
}
}
|
1
2
3
4
5
6
7
8
|
public
class
Shuffle2 {
public
static
void
main(String[] args) {
String[] str = {
"a"
,
"b"
,
"c"
,
"d"
,
"e"
,
"f"
};
//可以选择凑够52张牌
List<String> list = Arrays.asList(str);
Collections.shuffle(list);
System.out.println(list);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
|
public
interface
ListIterator<E>
extends
Iterator<E> {
boolean
hasNext();
E next();
boolean
hasPrevious();
E previous();
int
nextIndex();
//返回对 next 的下一个元素的索引。
int
previousIndex();
//返回对 previous 的上一个元素的索引
void
remove();
//可选
void
set(E e);
//可选
void
add(E e);
//可选
}
|
1
2
3
4
|
for
(ListIterator<Type> it = list.listIterator(list.size()); it.hasPrevious(); ) {
Type t = it.previous();
...
}
|
1
2
3
4
5
6
7
|
public
int
indexOf(E e) {
for
(ListIterator<E> it = listIterator(); it.hasNext(); )
if
(e ==
null
? it.next() ==
null
: e.equals(it.next()))
return
it.previousIndex();
// 元素不存在
return
-
1
;
}
|
1
2
3
4
5
|
public
static
<E>
void
replace(List<E> list, E val, E newVal) {
for
(ListIterator<E> it = list.listIterator(); it.hasNext(); )
if
(val ==
null
? it.next() ==
null
: val.equals(it.next()))
it.set(newVal);
}
|
1
2
3
4
5
6
7
8
9
|
public
static
<E>
void
replace(List<E> list, E val, List<?
extends
E> newVals) {
for
(ListIterator<E> it = list.listIterator(); it.hasNext();) {
if
(val ==
null
? it.next() ==
null
: val.equals(it.next())) {
it.remove();
for
(E e : newVals)
it.add(e);
}
}
}
|
List的截取操作
1
2
|
int
i = list.subList(fromIndex, toIndex).indexOf(object);
int
j = list.subList(fromIndex, toIndex).lastIndexOf(object);
|
注:如上搜索指定元素的方法,返回的字表的索引值,而不是原List的索引值。
1
2
3
4
5
6
7
|
public
static
<E> List<E> dealHand(List<E> deck,
int
n) {
int
deckSize = deck.size();
//扑克牌的(剩余)张数
List<E> handView = deck.subList(deckSize - n, deckSize);
List<E> hand =
new
ArrayList<E>(handView);
//发给这个人n张牌
handView.clear();
//已发的牌,需要从deck里删除
return
hand;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
public
class
Deal {
public
static
void
main(String[] args) {
// 52张扑克牌
String[] suit =
new
String[] {
"黑桃"
,
"红心"
,
"梅花"
,
"方块"
};
String[] rank =
new
String[] {
"A"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"10"
,
"J"
,
"Q"
,
"K"
};
// 初始化deck列表
List<String> deck =
new
ArrayList<String>();
for
(
int
i =
0
; i < suit.length; i++) {
for
(
int
j =
0
; j < rank.length; j++) {
deck.add(suit[i] + rank[j]);
}
}
dealing(deck,
4
,
13
);
// 4个玩家,每个玩家13张牌
}
//发牌,共有numHands玩家,每个玩家有cardsPerPerson张牌
public
static
<E>
void
dealing(List<E> deck,
int
numHands,
int
cardsPerPerson) {
// 洗牌
Collections.shuffle(deck);
if
(numHands * cardsPerPerson > deck.size()) {
System.out.println(
"玩家太多,扑克牌不足"
);
return
;
}
for
(
int
i =
0
; i < numHands; i++) {
System.out.println(dealHand(deck, cardsPerPerson));
}
}
public
static
<E> List<E> dealHand(List<E> deck,
int
n) {
int
deckSize = deck.size();
List<E> handView = deck.subList(deckSize - n, deckSize);
List<E> hand =
new
ArrayList<E>(handView);
handView.clear();
return
hand;
}
}
|
List 算法
-
sort
— 使用合并排序算法排序List,默认为升序排列。 -
shuffle
— 使用随机源对指定列表进行置换。(洗牌). -
reverse
— 反转指定列表中元素的顺序。 -
rotate
— 根据指定的距离轮换指定列表中的元素。 -
swap
— 交换指定位置上的元素 -
replaceAll
— 使用一个值替换列表中出现的所有某一指定值。 -
fill
— 使用指定元素替换列表中的所有元素。 -
copy
— 将所有元素从一个列表复制到另一个列表。 -
binarySearch
— 使用二分搜索法搜索指定列表,以获得指定对象。 -
indexOfSubList
— 返回指定列表中第一次出现指定目标列表的起始位置;如果没有出现这样的目标,则返回 -1。 -
lastIndexOfSubList
— 返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的目标,则返回 -1。