您的位置:首页 > 编程语言 > Java开发

java 集合框架(一)概述

2016-11-02 23:12 155 查看
Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。



在面向对象思想里,一种数据结构也被认为是一个容器。

Java集合框架支持以下两种类型的容器

1、为了粗存一个元素的集合,简称为集合(collection)

2、是为了存储键/值对,称为图(Map)

一、迭代器

迭代器是一个对象,它的工作是遍历并悬着序列中的对象,而客户端程序员不需要知道该序列底层的结构。统一了对容器的访问方式

public class IteratorTest {

public static void main(String[] args){

List<String> list = new ArrayList<String>(Arrays.asList(("a b c d e f g h i").split(" ")));

Iterator<String> iterator = list.iterator();//要求容器返回一个Iterator

while (iterator.hasNext()) {//检查序列中是否还有元素
System.out.print(iterator.next() + " ");
}

iterator = list.iterator();
for (int i = 0; i < 4; i++) {
iterator.next();//获得序列的下一个元素
iterator.remove();//将迭代器新近返回的元素删除
}

System.out.println(list);
}
}


Iterator还可以移除由next()产生的最后一个元素,这意味着在调用remove()之前必须调用next()

ListIterator接口扩展了Iterator接口,以增加对线性表的双向遍历能力。

可选操作

collection中的有些方法是不能再具体子类中实现的,在这种情况下,抛出异常java.lang.UnsupportedOperationException.可以防止出现接口爆炸的情况

public class Test{

static void test(String msg, List<String> list){

System.out.println("-----" + msg + "-----");
Collection<String> c = list;

System.out.println(c);

try {
c.clear();
} catch (Exception e) {
System.out.println("clear :" + e);
}

}

public static void main(String[] args){
List<String> list = Arrays.asList(("A B C D E F G H I J K L").split(" "));
test("modifiable", new ArrayList<String>(list));
test("unmodifiableList", list);
}
}


输出

-----modifiable-----
[A, B, C, D, E, F, G, H, I, J, K, L]
-----unmodifiableList-----
[A, B, C, D, E, F, G, H, I, J, K, L]
clear :java.lang.UnsupportedOperationException


因为Arrays.asList()会生成一个List,它基于一个固定大小的数组,仅支持哪些不会改变数组大小的操作

应该将Arrays.asList()的结果作为构造器的参数传递给任何Collection,这样就生成允许使用所有的方法的普通容器

比较器接口Comparator

Comparable是在集合内部定义的方法实现的排序,位于java.lang下。

Comparator是在集合外部实现的排序,位于java.util下。

Comparable是一个对象本身就已经支持自比较所需要实现的接口,如String、Integer自己就实现了Comparable接口,可完成比较大小操作。自定义类要在加入list容器中后能够排序,也可以实现Comparable接口,在用Collections类的sort方法排序时若不指定Comparator,那就以自然顺序排序。所谓自然顺序就是实现Comparable接口设定的排序方式。

Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。

Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。

Comparable:

public class Animal implements Comparable<Animal>{

private int age;

public Animal(int age) {
this.age = age;
}

public int getAge() {
return age;
}

@Override
public int compareTo(Animal o) {
// 实现Comparable接口要覆盖compareTo方法
return this.age - o.getAge();
}
}


Comparator:

public class AnimalComparator implements Comparator<Animal>{

@Override
public int compare(Animal o1, Animal o2) {
if(o1.getAge() > o2.getAge())
return -1;
else if (o1.getAge() == o2.getAge())
return 0;
else
return 1;
}

public static void fillSet(Set<Animal> set){
set.add(new Animal(1));
set.add(new Animal(2));
set.add(new Animal(3));
set.add(new Animal(4));
set.add(new Animal(5));
}

public static void printSet(Set<Animal> set){
for (Animal animal : set) {
System.out.print(animal.getAge() + " ");
}
System.out.println();
}

public static void main(String[] args){
Set<Animal> set = new TreeSet<Animal>();
Set<Animal> set1 = new TreeSet<Animal>(new AnimalComparator());
fillSet(set);
fillSet(set1);

printSet(set);
printSet(set1);

}

}


输出

1 2 3 4 5
5 4 3 2 1


若使用一个未实现Comparable接口的类

class Animal{
private int age;

public Animal(int age) {
this.age = age;
}

public int getAge() {
return age;
}
}

//....

public static void main(String[] args){
Set<Animal> set1 = new TreeSet<Animal>(new AnimalComparator());
fillSet(set1);
printSet(set1);

Set<Animal> set = new TreeSet<Animal>();
fillSet(set);
printSet(set);

}


结果

5 4 3 2 1
Exception in thread "main" java.lang.ClassCastException: com.example.collection.Animal cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(Unknown Source)


因为TreeSet并不知道该如何put

解决办法:

1、在构造TreeSet时指定一个比较器Comparator,这个比较器用于比较两个值,并且返回一个整数值作为他们的比较结果。

2、要实现Comparable接口。

二、集合

支持三种主要类型的集合:规则集(set), 线性表(List)和队列(Queue).这些集合的通用特性都被定义在接口中,它的实现是在具体类中提供的。

AbstractCollection类提供了Collection接口部分实现。

1、规则集(Set)

规定Set的实例不包含重复的元素

AbstracSet类提供equals和hashCode方法的具体实现

HashSet

可以储存互不相同的任何元素,添加到散列集中的对象必须以一种正确分散散列码的方式来实现hashCode()方法。散列集中的元素是没有特定顺序的。

LinkedHashSet

是一个用链表实现来扩展HashSet类,支持对规则集内的元素排序,保持元素插入时的顺序。元素必须定义hashCode()方法

TreeSet

确保规则集中的元素是有序的,只要对象是可以相互比较的,就可以将它们添加到一个树形集中

使用Comparable接口中的CompareTo方法对树形集排序

2、线性表(List)

允许在一个集合中存储重复的元素,而且用户可以指定他们的存储位置,通过下标来访问元素。

1、ArrayList,由数组支持,在中间插入和移除元素时较慢

2、LinkedList,由链表实现,它通过代价较低的插入和删除操作,提供了优化的顺序访问,在随机访问方面比较慢。

规则表比线性表更加高效,如果应用程序用规则集就足够,就使用规则集。

3、队列(Queue)

队列是一种先进先出的数据结构,元素被追加在队列末尾,然后从队列头删除。在优先队列中,拥有最高优先级的元素首先被删除。

可以使用LInkedList创建一个队列

4、图

依照键值存储元素的容器。

HashMap

不会根据插入的顺序将键值对进行排序,并且存储顺序是随机的。

LinkedHashMap

用链表实现来扩展HashMap,支持图中条目的排序。

1、按照插入图的顺序排序

2、按最后一次访问的顺序,从最早到最晚(访问顺序)

TreeMap

在遍历排好顺序的键值时是很高效的,键值使用Comparable或Comparator来排序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java