java 集合框架(一)概述

来源:互联网 发布:nba2k18球星捏脸数据 编辑:程序博客网 时间:2024/04/27 10:58

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来排序。

0 0
原创粉丝点击