您的位置:首页 > 职场人生

黑马程序员——Java中集合框架总结

2015-08-11 17:42 363 查看
------Java培训、Android培训、期待与您交流! -------

一、集合类概述

1、集合类的由来

对象用于封装特有数据, 对象多了需要存储; 如果对象的个数不确定, 就使用集合容器进行存储。

2、集合与数组的区别

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

3、集合框架

集合容器因为内部的数据结构不同, 有多种具体容器。不断的向上抽取, 就形成了集合框架。



二、Collection接口

1、常见方法

1.1 添加。

boolean add(Object obj):添加对象

boolean addAll(Collection coll):添加集合

1.2 删除。

boolean remove(object obj):移除对象

boolean removeAll(Collection coll);移除集合

void clear();清空集合

1.3 判断:

boolean contains(object obj):是否包含某个对象

boolean containsAll(Colllection coll);是否包含某个集合

boolean isEmpty():判断集合中是否有元素。

1.4 获取:

int size():集合长度

Iterator iterator():迭代器

1.5 其他:

boolean retainAll(Collection coll);取交集。

Object[] toArray():将集合转成数组。

范例:

//Collection常用方法演示
import java.util.*;

public class CollectionDemo {

public static void main(String[] args) {
// 创建集合对象
Collection coll = new ArrayList();
show(coll);

System.out.println("-------------------------------");

Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
show(c1, c2);

}

public static void show(Collection c1, Collection c2) {

// 给c1添加元素。
c1.add("abc1");
c1.add("abc2");
c1.add("abc3");
c1.add("abc4");

// 给c2添加元素。
c2.add("abc1");
c2.add("abc2");
c2.add("abc3");
c2.add("abc4");
c2.add("abc5");

System.out.println("c1:" + c1);
System.out.println("c2:" + c2);

// 演示addAll

c1.addAll(c2);// 将c2中的元素添加到c1中。

// 演示removeAll
boolean b = c1.removeAll(c2);// 将两个集合中的相同元素从调用removeAll的集合中删除。
System.out.println("removeAll:" + b);

// 演示containsAll
boolean b1 = c1.containsAll(c2);
System.out.println("containsAll:" + b1);

// 演示retainAll
boolean b2 = c1.retainAll(c2);// 取交集,保留和指定的集合相同的元素,而删除不同的元素。
// 和removeAll功能相反 。
System.out.println("retainAll:" + b2);
System.out.println("c1:" + c1);

}

public static void show(Collection coll) {

// 添加元素。add.
coll.add("abc1");
coll.add("abc2");
coll.add("abc3");
System.out.println(coll);

// 删除元素。remove
coll.remove("abc2");// 会改变集合的长度

// 清空集合.
// coll.clear();

System.out.println(coll.contains("abc3"));
System.out.println(coll);
}
}
输出结果:

[abc1, abc2, abc3]

true

[abc1, abc3]

-------------------------------

c1:[abc1, abc2, abc3, abc4]

c2:[abc1, abc2, abc3, abc4, abc5]

removeAll:true

containsAll:false

retainAll:false

c1:[]

三、Iterator接口

1、Iterator概述

Iterator接口主要用于遍历Collection集合中的元素,也成为迭代器。Iterator接口就是对所有的Collection容器进行元素取出的公共接口。因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。

2、常用方法

boolean hasNext():若被迭代的集合元素还没有被遍历,返回true.

Object next():返回集合的下一个元素.

void remove():删除集合上一次next()方法返回的元素。(若集合中有多个相同的元素,都可以删掉)

3、集合遍历输出方式

Iterator、for each循环、for循环、转成数组后再用for each循环。

范例
/遍历输出的四种方式

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorTest {
public static void main(String[] args) {

List<String> l = new ArrayList();

l.add("1");
l.add("2");
l.add("3");
l.add("4");

System.out.println(l);

// 遍历输出:四种方式

// 1、推荐使用的Iterator对象,迭代输出
Iterator it = l.iterator();
while (it.hasNext()) {
System.out.println("迭代输出:" + it.next());
}

// 2、对集合进行for each循环!
for (String str : l) {
System.out.println("for each输出:" + str);
}

// 3、for循环迭代,在for方法体内部实例化Iterator对象!
int i = 0;// for方法体内定义项不能出现多种不同类型
for (Iterator iter = l.iterator(); i < l.size(); i++) {
System.out.println("for循环输出:" + iter.next());
}

// 4、先将集合转换为数组,再利用数组的遍历输出;
Object[] o = l.toArray();
for (Object object : o) {
System.out.println("转换数组迭代输出:" + object);
}
}
}


输出结果:

[1, 2, 3, 4]

迭代输出:1

迭代输出:2

迭代输出:3

迭代输出:4

for each输出:1

for each输出:2

for each输出:3

for each输出:4

for循环输出:1

for循环输出:2

for循环输出:3

for循环输出:4

转换数组迭代输出:1

转换数组迭代输出:2

转换数组迭代输出:3

转换数组迭代输出:4

四、list、set接口

1、概述

List:有序(存入和取出的顺序一致),元素都有索引,允许重复元素。

Set:元素不能重复,无序。

2、list接口常用方法

2.1 添加

void add(index,element):指定位置增加元素

void addAll(index,collection):指定位置增加集合中所有元素

2.2 删除

Object remove(index):删除指定位置的元素

2.3 修改

Object set(index,element):修改指定位置的元素

2.4 获取:

Object get(index):获取指定位置的元素

int indexOf(object):获取元素第一次出现的位置,没有返回-1

int lastIndexOf(object):获取元素最后一次出现的位置

List subList(from,to):获取子集合

2.5 其他方法

List Iterator():list集合特有的迭代器方法。

范例:

//ListIterator演示
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ListDemo2 {

public static void main(String[] args) {

// 创建集合并添加元素
List list = new ArrayList();

list.add("abc1");
list.add("abc2");
list.add("abc3");

System.out.println("list:" + list);
ListIterator it = list.listIterator();
// 获取列表迭代器对象,它可以实现在迭代过程中完成对元素的增删改查。只有list集合具备该迭代功能.

// Iterator it = list.iterator();
// 在迭代器过程中, 不要使用集合操作元素, 容易出现异常:java.util.Concurrent
// ModificationException。
// 可以使用Iterator接口的 子接口ListIterator来完成在迭代中对元素进行更多的操作。

// 迭代输出
while (it.hasNext()) {
Object obj = it.next();
if (obj.equals("abc2")) {
it.set("abc9");// set方法
}
}
System.out.println("hasNext:" + it.hasNext());// 判断是否有下一个元素
System.out.println("hasPrevious:" + it.hasPrevious());// 判断是否有前一个元素

// 迭代取出前一个元素
while (it.hasPrevious()) {
System.out.println("previous:" + it.previous());//
}
System.out.println("list:" + list);
}


输出结果:

list:[abc1, abc2, abc3]

hasNext:false

hasPrevious:true

previous:abc3

previous:abc9

previous:abc1

list:[abc1, abc9, abc3]

3、Vector、ArrayList、LinkedList

3.1 概述

Vector:内部是数组数据结构,是同步的。增删,查询都很慢。

ArrayList:内部是数组数据结构,是不同步的,替代了Vector。 替代了Vector, 查询的速度快。

LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。

3.2 Vector常用方法

addElement(obj);//添加元素,相当于add(obj);

Enumerationelements();//Vector特有取出方式(枚举)

hasMoreElements();//相当于Iterator的hasNext()方法

nextElements();//相当于Iterator的next()方法

3.3 LinkedList常用方法

addFirst()/offerFirst():在首添加元素

addLast()/offerLast():在尾添加元素

getFirst()/peekFirst():获取第一个元素

getLast()/peekLast():获取最后一个元素

removeFirst()/pollFirst():获取并移除第一个元素

removeLast()/pollLast():获取并移除最后一个元素

注:/后为JDK1.6版本之后的方法。

范例:
/*
* 使用LinkedList来模拟一个堆栈或者队列数据结构。
* 堆栈:先进后出 First In Last Out FILO
* 队列:先进先出 First In First Out FIFO
*/
import java.util.LinkedList;

public class MyStack {
private LinkedList link;

public MyStack() {
link = new LinkedList();
}

// 堆栈的添加元素的功能

public void myAdd(Object obj) {
link.addFirst(obj);
}

// 堆栈的移除元素的功能

public Object myGet() {
return link.removeFirst();
}

// 堆栈的判断是否包含元素的功能

public boolean isNull() {
return link.isEmpty();
}
}

public class LinkedListDemo {

public static void main(String[] args) {

//创建集合对象,并添加元素
MyStack s = new MyStack();

s.myAdd("abc1");
s.myAdd("abc2");
s.myAdd("abc3");
s.myAdd("abc4");

//堆栈输出
while (!s.isNull()) {
System.out.println(s.myGet());
}
}
}


输出结果:

abc4

abc3

abc2

abc1

4、Set接口

4.1 概述

Set接口中的元素不可以重复,是无序的。Set接口中的方法和Collection一致。Set接口包括HashSet和TreeSet两个子类。

HashSet: 内部数据结构是哈希表,是不同步的。

TreeSet: 可以对Set集合中的元素进行排序,是不同步的。

4.2 HashSet

HashSet是通过对象的hashCode和equals方法来完成对象唯一性的。使用HashSet集合存储元素,必须覆盖hashCode方法和equals方法。

哈希表确定元素是否相同:首先判断的是两个元素的哈希值是否相同,用到的是hashCode方法。如果相同,在判断两个对象的内容是否相同,用到的是equals方法。如果哈希值不同,是不需要判断equals。

范例:
//HashSet集合存储元素演示

import java.util.HashSet;
import java.util.Iterator;

// 往HashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。

//定义一个Person类
public class Person {

private String name;
private int age;

public Person() {
super();
}

// 构造函数初始化
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}

@Override
// 覆盖hashCode方法
public int hashCode() {
return name.hashCode() + age * 27;
}

@Override
// 覆盖equals方法
public boolean equals(Object obj) {
if (this == obj)
return true;// 相同返回True
if (!(obj instanceof Person))// 健壮性判断
throw new ClassCastException("类型错误");

Person p = (Person) obj;// 使用子类特有方法
return this.name.equals(p.name) && this.age == p.age;
}

// set、get方法
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

public class HashSetTest {

public static void main(String[] args) {

//创建HashSet集合
HashSet hs = new HashSet();

//添加对象元素
hs.add(new Person("小明", 24));
hs.add(new Person("小红", 27));
hs.add(new Person("小强", 21));
hs.add(new Person("小磊", 29));
hs.add(new Person("小丽", 27));

//迭代输出
Iterator it = hs.iterator();

while (it.hasNext()) {
Person p = (Person) it.next();//it.next()为Object类型
System.out.println(p.getName() + "...." + p.getAge());
}
}
}


输出结果:

小磊....29

小红....27

小强....21

小明....24

小丽....27

4.3 TreeSet

TreeSet判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存储;反之,则存储。

TreeSet对元素进行排序:

方式一:实现Comparable接口,覆盖compareTo方法;

方式二:让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeSet集合的构造函数。

TreeSet集合的底层是使用二叉树进行排序的。

范例:
//TreeSet集合存储元素演示
import java.util.Iterator;
import java.util.TreeSet;
import java.util.Comparator;

//实现Comparator接口,创建自定义比较器
public class ComparatorByLength implements Comparator {

@Override
// 覆盖compare方法
public int compare(Object o1, Object o2) {

String s1 = (String) o1;
String s2 = (String) o2;

int temp = s1.length() - s2.length();

return temp == 0 ? s1.compareTo(s2) : temp;
}

}

//对给定字符串按照长度排序
public class TreeSetTest {

public static void main(String[] args) {

//创建集合,将自定义比较器作为参数传入
TreeSet ts = new TreeSet(new ComparatorByLength());

//添加元素
ts.add("abc");
ts.add("de");
ts.add("bcd");
ts.add("ddddd");
ts.add("eacg");

//迭代输出
Iterator it = ts.iterator();

while (it.hasNext()) {
System.out.println(it.next());
}
}
}


输出结果:

de

abc

bcd

eacg

ddddd

五、Map接口

1、Map集合概述

Map集合存储元素是一次添加一对元素,也称为双列集合。

Collection 一次添加一个元素,也称为单列集合。

Map集合中存储的是键值对,即Map<K,V>,建立了键(Key)和值(Value)的映射。必须保证键的唯一性。

2、Map接口中常用方法

value put(key,value):添加元素,返回前一个和key关联的值,若无返回null。

void clear():清空map集合。

value remove(key):根据指定的key移除这个键值对。

boolean containsKey(key):判断是否包含键。

boolean containsValue(value):判断是否包含值。

boolean isEmpty();判断集合是否为空。

value get(key):通过键获取值,如果没有该键返回null。

int size(): 获取键值对的个数.

3、Map接口中的子类

Hashtable :内部结构是哈希表,同步。不允许null作为键,null作为值。

Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。 HashMap : 内部结构是哈希表,不同步。允许null作为键,null作为值。

TreeMap : 内部结构是二叉树,不同步。可以对Map集合中的键进行排序。

4、Map集合中元素取出方式

Map集合的取出原理:将Map集合转成Set集合,再通过迭代器取出。

方式一: keySet()方法
a95d
:将Map中所有的键存入到Set集合中,然后通过迭代方式取出这些键的值,再通过get方法获取每一个键对应的值。

范例:
//keySet方法演示
import java.util.*;

public class KeySetDemo {
public static void main(String[] args) {

// 创建Map集合
Map<Integer, String> m = new HashMap<Integer, String>();

// 添加元素
m.put(1, "jack");
m.put(2, "rose");
m.put(3, "lucy");

Set<Integer> s = m.keySet();// 得到的是key的集合
Iterator<Integer> it = s.iterator();// 然后将key迭代出来
while (it.hasNext()) {
Integer key = it.next();
System.out.println(key + ":" + m.get(key));
}
}
}


输出结果:

1:jack

2:rose

3:lucy

方式二:entrySet()方法:将Map集合中的映射关系作为对象存入到Set集合中,而这个映射关系的类型为Map.Entry。然后通过迭代方法取出这些对象。

范例:
//entrySet方法演示
import java.util.*;
import java.util.Map.Entry;

public class EntrySetDemo {

public static void main(String[] args) {

// 创建Map集合
Map<Integer, String> m = new HashMap<Integer, String>();

// 添加元素
m.put(1, "jack");
m.put(2, "rose");
m.put(3, "lucy");

Set<Entry<Integer, String>> s = m.entrySet();// 存入Set集合
Iterator<Entry<Integer, String>> it = s.iterator();//迭代输出
while (it.hasNext()) {
Entry<Integer, String> me = it.next();
System.out.println(me.getKey() + ":" + me.getValue());
}
}

}


输出结果:

1:jack

2:rose

3:lucy

5、Map集合应用

查表法:表中元素具有映射关系,因此优先使用Map集合。
//Map集合在查表法中的运用
import java.util.HashMap;
import java.util.Map;

public class MapTest {

public static void main(String[] args) {

String week = getWeek(4);//
System.out.println(week);

System.out.println(getWeekByMap(week));
}

// 创建Map集合存储星期中文和英文简写格式的对应关系
public static String getWeekByMap(String week) {

Map<String, String> map = new HashMap<String, String>();

map.put("星期一", "Mon.");
map.put("星期二", "Tues.");
map.put("星期三", "Wed.");
map.put("星期四", "Thur.");
map.put("星期五", "Fri.");
map.put("星期六", "Sat.");
map.put("星期日", "Sun.");

return map.get(week);
}

// 根据输入数字返回对应星期中文格式
public static String getWeek(int week) {

if (week < 1 || week > 7)
throw new RuntimeException("没有对应的星期,请您重新输入");

String[] weeks = { "", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };

return weeks[week];
}

}


输出结果:

星期四

Thur.

六、集合框架总结

存储元素需要保持唯一性吗?

需要:Set

需要制定顺序:

需要: TreeSet

不需要:HashSet

但是想要有序:LinkedHashSet

不需要:List

需要频繁增删吗?

需要:LinkedList

不需要:ArrayList

存储元素具有映射关系:Map

看名字记住容器的结构和所属体系:

List:

|--ArrayList

|--LinkedList

Set:

|--HashSet

|--TreeSet

Map:

|--Hashtable

|--HashMap

|--TreeMap

后缀名就是该集合所属的体系。

前缀名就是该集合的数据结构。

看到array:就要想到数组,就要想到查询快,有角标。

看到link:就要想到链表,就要想到增删快,就要想要 add get remove+frist last的方法 。

看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashcode方法和equals方法。

看到tree:就要想到二叉树,就要想要排序,就要想到两个接口Comparable,Comparator 。

而且通常这些常用的集合容器都是不同步的。

------Java培训、Android培训、期待与您交流! -------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: