Java基础之-----集合框架
来源:互联网 发布:史丹利快报的淘宝店 编辑:程序博客网 时间:2024/04/25 07:20
Java集合框架包括:— interfaces, implementations, aggregate operations, and algorithms (接口,实现,聚合操作和算法),这些组成了Java集合框架的核心。其中:
- 接口是Java集合框架的灵魂
- 实现介绍了Java一些常用的集合实现
- 聚合操作是JDK8提供的新功能,能够方便的实现集合类型的转换
- 算法定义了Java用于集合操作的多态算法
集合简介
集合,有时也称作容器,是用来存储、检索、操作和传递集合数据的。它代表同类数据的一个集合。
集合框架是用来操作集合的一个统一的框架,所有的集合框架都包括接口、实现和算法三部分。另外JDK8还新添加了聚合操作,提供了更加强大的功能。
接口是代表集合的抽象数据类型,,它使得对集合的操作独立于集合的具体实现,所有的接口通常形成层级关系。
实现是接口的具体实现类型。本质上,他们是可重用的数据类型
算法是用来对实现接口的对象执行有用的操作。算法通常具有多态行为,本质上他们是可重用的方法。
接口
核心接口是Java 集合框架的基础,Java的核心集合接口封装了很多不同类型的Java集合,他们组成了一个层级关系。如下所示:
可以看到,Java的核心集合接口,由两颗不同的层级树组成。
Java集合接口都是泛型,所以在使用的时候一定要指定接口所操作的类型,以便于编译器进行编译时类型检查,避免运行时错误。
可以看出,这个层级关系分为两个不同的树:Collection和Map,下面对这两个不同的树进行详细的介绍。
Collection :是Java集合的根。是所有集合实现的最小公分母。
Set :是不包含重复元素的集合,它是对数学上集合概念的建模。
SortedSet :它是一个按升序管理元素的set,比如单词表
List :是一个有序的集合,通常称为序列,允许包含重复元素。
Queue :是一个用来在处理前保存数据的集合,它除了集合的操作外,还有一些额外的操作:插入、删除、检查等。通常Queue采用先进先出的顺序排列元素但不是必须的。每一个Queue 的实现,都需要指定它的排序属性,用来定义如何排序。在FIFO Queue 里,总是在头部删除,在尾部插入。不管Queue 是如何排序,总是在头部执行remov和poll操作。
Deque :也是用来保存将要处理的数据的,除了集合操作外,添加了插入、删除、检查等操作。Deque 既可以是FIFO,也可以是LIFO的,和Queue 不同的是,Deque的两端都可以执行插入删除和检索操作。
Map :是一个将Key映射到value的对象,不允许有重复的key,并且一个key最多只能有一个value与之对应。
SortedMap :是一个按升序方式管理键值对的Map。
Set
Set是一个不允许有重复元素的Collection,它只有从Collection继承过来的接口,同时添加了不允许重复元素的限制,加强了对equals()和hashCode()的定义,允许比较两个不同的实现类型的set,当且仅当两个set含有一样的元素。
Java提供了三种常用的Set的实现类:HashSet、TreeSet、LinkedHashSet。
HashSet:用HashTable存储元素,有最好的性能,但是不保证一致的迭代顺序
TreeSet:用红黑树存储元素,按值排列元素,比HashSet慢,
LinkedHashSet:用一个链表实现hash table,以插入顺序排列元素。性能和HashSet差不多。
需要主要的是HashSet的迭代和元素的总个数和Set的大小线性相关,初始大小太大,浪费了内存,太大,浪费时间。如果不指定,默认大小是16,而且的内部处理是去最接近的2的整数次幂,另外,Hashset有一个调节参数叫装填因子。LinkedHashSet有装填因子,而TreeSet没有。
Java还提供了两种特殊的实现: EnumSet 和 CopyOnWriteArraySet.
set的基本操作
Java提供了一些set的基本操作,包括:size、isEmpty 、add 、remove 、iterator。这些操作都是基本的操作,功能也一目了然。
Set的块操作
set的块操作实际执行的是集合的代数运算:包含,交并补等操作
s1.containsAll(s2):包含
s1.addAll(s2)并集
s1.retainAll(s2)交集
s1.removeAll(s2)补集
注意:对集合进行交并补操作的时候,会改变s1,s1就是操作后的结果,也就是这些操作都有副作用。为了不改变s1,应该对s1的副本做操作。如下:
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);
这样就避免了操作的副作用。
另外,利用以上提供的块操作,我们还可以对集合求对称差集:集合的并集和集合的交集的差集就是集合的对称差集。代码如下:
Set<Type> symmetricDiff = new HashSet<Type>(s1);symmetricDiff.addAll(s2);Set<Type> tmp = new HashSet<Type>(s1);tmp.retainAll(s2);symmetricDiff.removeAll(tmp);
List
List是一个有序的Collection,也称作序列,除了Colection定义的操作外,它还添加了以下几种类型的操作
按位存取 按元素在list中的数值位置访问元素,包括:get, set, add, addAll, and remove.
其中set 和 remove返回的是操作之前的值。
定位 返回指定对象返回其在list中的位置,包括:indexOf 、 lastIndexOf.
迭代 利用list的线性特性,继承了迭代器的语法,包括: listIterator 返回的是一个ListIterator,继承自Iterator,但同时它增加了向前迭代的功能,同时也支持按位访问 范围视图 获得list任意长度的子序列,包括:sublist 对sublist的修改同样也会作用于List本身
Java提供了三种常用的List:
ArrayList:它的优点是能够实现元素的随机访问,能够利用System.arraycopy同时移动多个元素 ,它有调节参数,线程不安全
LinkedList:当需要频繁的在list的头部添加元素或者平凡的通过迭代器删除元素时,可以考虑用LInkedList。没有调节参数,同时实现了Queue接口,线程不安全 Vector:线程安全的,当需要考虑同步的时候,使用
同样,List也提高了equals 和 hashCode的要求,这样两个不同实现的list可以做逻辑上的比较操作,当且仅当两个list含有相同的元素而且顺序一样,两个list才相等。
Queue
用来保存预处理的元素,除了Collection的操作,还添加了插入、删除、检查操作,如下:
public interface Queue<E> extends Collection<E> { boolean add(E e); boolean offer(E e); E remove(); E poll(); E element(); E peek();}
所有的这六个方法可以分为两种形式:
- 操作失败后抛出异常
- 操作失败后返回特殊的值
通常Queue采用先进先出的顺序排列元素但不是必须的。每一个Queue 的实现,都需要指定它的排序属性,用来定义如何排序。在FIFO Queue 里,总是在头部删除,在尾部插入。不同的队列可能采取不同的排序规则。不管Queue 是如何排序,总是在头部执行remov和poll操作。
一些Queue会限制元素的个数,这样的队列是有限的,java.util.concurrent 里实现的队列都是有限的,java.util 里的实现不是的。
add 和offer
用于执行入队操作。
add用于向队列插入元素,当它用于向有界队列插入元素时,如果越界,则会抛出IllegalStateException
offer:专门用来向有界队列插入元素,不同于add是,如果越界,则返回false
remove和poll
用于执行出队操作,移除并返回队列头部的元素,但是具体哪个元素被移除,和队列的排序策略有关。两者不同之处是,当队列为空时,前者抛出NoSuchElementException,后者返回null
element和peek
返回但不移除队列头部的元素,二者的区别是,当队列为空时,前者抛出NoSuchElementException,后者返回null
队列默认是不允许插入null的,但是LinkedList实现确允许插入null。尽管如此,应当避免这种用法,因为pool和peek会使用这个特殊值。
Queue没有实现基于元素的equals和hashCode,而是继承自Object。同时也没有实现队列阻塞方法,而是在 java.util.concurrent.BlockingQueue中定义了阻塞方法,这个接口继承自Queue,这在并发编程中需要用到。
实现:LinkedList和PriorityQueue
Deque
双端队列是一个支持在两端执行插入删除操作的线性集合,它是一个比Stack和Queue丰富的抽象数据类型,因为它同时实现了Stack和Queue的功能。它提供了在两端进程插入、删除和检查元素的接口。
ArrayDeque和LinkedList都是Deque的实现类
它既可以当做FIFO队列又可以当做LIFO队列。
Deque提供了12个方法,用于对两端元素进行操作,如下:
这些方法的区别是,在操作失败是有些抛出异常,有些返回特定的值,这个和Queue类似。
同时,Deque还提供removeFirstOccurence和removeLastOccurence,这两个方法顾名思义,当不存在时返回false。
Java提供了两种常用的Deque:
LinkedList:比ArrayDeque灵活,允许插入null,但是插入和删除效率差,耗内存
ArrayDeque:性能好,节约内存,但是不允许插入null。
Map
是一个将Key映射成Value的对象,一个map不能含有重复的key,一个key最多对应一个value,它是对数学函数的抽象建模。
它主要提供
- 基本操作:put, get, remove, containsKey, containsValue, size,empty
- 块操作:putAll, clear
- 集合视图: keySet, entrySet, values
Java提供了三种常用的Map的实现类: HashMap, TreeMap, and LinkedHashMap. 和Set的常用实现一样 HashMap:key 的顺序不确定,性能最好 TreeMap :实现了key按值的升序排列,性能比HashMap差 LinkedHashMap. key按put的先后顺序排列,性能和HashMap差不多。需要注意的是,LinkedHashMap和LinkedHashSet不同,首先,它的排序顺序是按访问的频率的高低,访问频率越低,会被排到后面,同时,LinkedHashMap提供了removeEldestEntry(),这样可以通过重写这个方法,当添加新的元素的时候,自动的删除陈旧的元素,利用它可以实现缓存cache。
同样,Map也提高了equals 和 hashCode的要求,实现不同Map实现的比较,两个map相等,当且仅当他们的映射关系相同。
对象的排序
当我们需要对一个List的元素进行排序时,可以采用如下做法
Collections.sort(list);//list是一个List类型对象
但是前提是list里的元素实现了Comparable接口,如果没有实现Comparable,那么,会抛出ClassCastException。Java提供了一些实现了Comparable接口的类。
当需要比较两个对象时,可以使用:
public interface Comparator<T> {int compare(T o1, T o2);}
接口
SortedSet
该类提供了按某种方式排序的Set。
public interface SortedSet<E> extends Set<E> { Comparator<? super E> comparator(); //range View SortedSet<E> subSet(E fromElement, E toElement); SortedSet<E> headSet(E toElement); SortedSet<E> tailSet(E fromElement); //end point E first(); E last();}
SortedMap
和SoredSet一样,这里就不说了。
- Java基础之集合框架
- java基础之集合框架
- Java基础之集合框架
- java基础之集合框架
- JAVA基础之集合框架
- Java基础之-----集合框架
- Java基础之集合框架
- Java基础之集合框架
- java基础之集合框架
- java基础之集合框架
- JAVA基础之集合框架
- java基础-- 集合框架 之 Set集合
- java基础-- 集合框架 之 Map集合
- 【java基础】Java集合框架之小结
- Java基础之十三:Java集合框架
- java 基础之集合框架-----05
- java基础_ 集合框架之Collection
- Java基础--集合框架之Set
- CentOS7搭建lamp
- 欢迎使用CSDN-markdown编辑器
- 5 异常、finally、权限、jar包、模板模式
- 关于游戏程序员的职业规划
- HDU-1005 Number Sequence && 51NOD-1126 求递推序列的第N项
- Java基础之-----集合框架
- Socket网络编程详解
- 迪杰斯特拉算法C++实现
- Python-装饰器以及对带有参数的装饰器的理解
- AFNetworking 原作者都无法解决的问题: 如何使用ip直接访问https网站?
- Codeforces 617C Watering Flowers 【暴力 数据范围】
- Java 包
- c中定义变量的内存分配顺序问题(极易错!!!)
- Codeforces 617A Elephant