集合框架
早在 Java 2 中之前,Java 就提供了特设类。比如:Dictionary
, Vector
, Stack
, 和 Properties
这些类用来存储和操作对象组。
虽然这些类都非常有用,但是它们缺少一个核心的,统一的主题。由于这个原因,使用 Vector
类的方式和使用 Properties
类的方式有着很大不同。
集合框架被设计成要满足以下几个目标:
- 该框架必须是高性能的。基本集合(动`态数组,链表,树,哈希表)的实现也必须是高效的。
- 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
- 对一个集合的扩展和适应必须是简单的。
为此,整个集合框架就围绕一组标准接口而设计。你可以直接使用这些接口的标准实现,诸如: LinkedList
**, **HashSet
, 和 TreeSet
等,除此之外你也可以通过这些接口实现自己的集合。
从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合Collection
,存储一个元素集合,另一种是图Map
,存储键/值对映射。Collection
接口又有 3 种子类型,List
、Set
和 Queue
,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList
、LinkedList
、HashSet
、LinkedHashSet
、HashMap
、LinkedHashMap
等等。
集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:
- 接口:是代表集合的抽象数据类型。例如
Collection
、List
、Set
、Map
等。之所以定义多个接口,是为了以不同的方式操作集合对象 - 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:
ArrayList
、LinkedList
、HashSet
、HashMap
。 - 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
除了集合,该框架也定义了几个 Map
接口和类。Map
里存储的是键/值对。尽管 Map
不是集合,但是它们完全整合在集合中。
接口
接口名称 | 接口描述 |
---|---|
Collection 接口 |
Collection 是最基本的集合接口,一个 Collection 代表一组 Object ,即 Collection 的元素, Java不提供直接继承自Collection 的类,只提供继承于的子接口(如List 和Set )。Collection 接口存储一组不唯一,无序的对象。Collection 接口才可以使用foreach 循环。 |
List 接口 |
List 接口是一个有序的 Collection ,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。 |
Set 接口 |
Set 接口具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。 |
SortedSet 接口 |
继承于Set 保存有序的集合。 |
Map 接口 |
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。 |
Map.Entry |
Map.Entry 描述在一个Map中的一个元素(键/值对)。是一个 Map 的内部接口。 |
SortedMap 接口 |
SortedMap 接口继承于 Map,使 Key 保持在升序排列。 |
Enumeration 接口 |
Enumeration 接口是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。 |
-
Set
和List
的区别-
Set
接口实例存储的是无序的,不重复的数据。List
接口实例存储的是有序的,可重复的元素。 -
Set
检索效率低,删除和插入效率高,插入和删除不会引起元素位置改变 (实现类有HashSet
、TreeSet
)。 -
List
和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List
的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变。 (实现类有ArrayList
、LinkedList
、Vector
)
-
集合实现类(集合类)
类名称 | 类描述 |
---|---|
AbstractCollection |
AbstractCollection 实现了大部分的集合接口。 |
AbstractList |
AbstractList 继承于AbstractCollection 并且实现了大部分List接口。 |
AbstractSequentialList |
AbstractSequentialList 继承于 AbstractList ,提供了对数据元素的链式访问而不是随机访问。 |
LinkedList |
LinkedList 该类实现了List 接口,允许有null 元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List ,则必须自己实现访问同步,解决方法就是在创建List 时候构造一个同步的List 。例如:List list=Collections.synchronizedList(newLinkedList(...));``LinkedList 查找效率低。 |
ArrayList |
ArrayList 该类也是实现了List 的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。 |
AbstractSet |
AbstractSet 继承于AbstractCollection 并且实现了大部分Set 接口。 |
HashSet |
HashSet 该类实现了Set 接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null 的元素,但最多只能一个。 |
LinkedHashSet |
LinkedHashSet 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。 |
TreeSet |
TreeSet 该类实现了Set 接口,可以实现排序等功能。 |
AbstractMap |
AbstractMap 实现了大部分的Map接口。 |
HashMap |
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 该类实现了Map 接口,根据键的HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为null ,不支持线程同步。 |
TreeMap |
TreeMap 继承了AbstractMap ,并且使用一颗树。 |
WeakHashMap |
WeakHashMap 继承AbstractMap 类,使用弱密钥的哈希表。 |
LinkedHashMap |
LinkedHashMap 继承于HashMap ,使用元素的自然顺序对元素进行排序. |
IdentityHashMap |
IdentityHashMap 继承AbstractMap 类,比较文档时使用引用相等。 |
Vector |
Vector 该类和ArrayList 非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。 |
Stack |
Stack 栈是Vector 的一个子类,它实现了一个标准的后进先出的栈。 |
Dictionary |
Dictionary 类是一个抽象类,用来存储键/值对,作用和Map类相似。 |
Hashtable |
Hashtable 是 Dictionary 类的子类,位于 java.util 包中。 |
Properties |
Properties 继承于 Hashtable ,表示一个持久的属性集,属性列表中每个键及其对应值都是一个字符串。 |
BitSet |
BitSet 一个Bitset 类创建一种特殊类型的数组来保存位值。BitSet 中数组大小会随需要增加。 |
迭代器
迭代器,可以通过循环来得到或删除集合的元素。
Iterable
是一个定义集合遍历方式的接口,有方法 iterator()
获取迭代器对象,因此实现了Iterable
接口的类才可以使用for-each
循环遍历,例如实现了Collection
接口的类。
Iterator
是一个定义了集合迭代器的借口,有方法 hasNext()
、next()
、remove()
来使用迭代器对集合进行遍历操作。
ListIterator
继承了 Iterator
,以允许双向遍历列表和修改元素,List
接口可以使用双向迭代器。
public class Test{
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("HAHAHAHA");
// 第一种遍历方法使用 For-Each 遍历 List
for (String str : list) { //也可以改写 for(int i=0;i<list.size();i++) 这种形式
System.out.println(str);
}
// 第二种遍历,把链表变为数组相关的内容进行遍历
String[] strArray = new String[list.size()];
list.toArray(strArray);
for(int i=0; i < strArray.length; i++) // 可以改写为 for(String str:strArray) 这种形式
{
System.out.println(strArray[i]);
}
// 第三种遍历 使用迭代器进行相关遍历
Iterator<String> ite=list.iterator();
while(ite.hasNext()) // 判断下一个元素之后有值
{
System.out.println(ite.next());
}
}
}
比较器
TreeSet
和 TreeMap
的按照排序顺序来存储元素。这是通过实现了比较器接口 Comparator
来精确定义按照什么样的排序顺序,这个接口可以以不同的方式来排序一个集合。
Comparable
是自然排序使用的接口,提供的方法compareTo(T o)
实现,当一个类实现了Comparable
接口,就意味着该类支持排序。
Comparator
是比较器接口,可以实现此接口自定义排序规则,用自定义的比较器入参,可以完成集合的自定义排序,例如 compare(E a, E b)
返回值为 int
类型。
注:当自然排序与自定义比较器同时使用,自定义比较器优先级更高。
Comparable
与 Comparator
比较:
用 Comparable
简单, 只要实现 Comparable
接口的对象直接就成为一个可以比较的对象,但是需要修改源代码;
用 Comparator
的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去即可进行比较。
判断重复的标准:
调用对象的compareTo
方法进行升序排列(A.compareTo(B)
),如果return 0
表示相等;返回值大于0,则认为A大于B;如果返回值小于0,则认为A小于B。
Collections工具类
用于操作Collection
下的集合。
方法 | 描述 |
---|---|
addAll(Collection c, Object... elements) |
将所有指定的元素elements添加到指定的集合c中。 |
fill(List list, Object obj) |
用指定的元素obj代替指定集合list中的所有元素。(批量初始化) |
max(Collection coll) |
根据自然顺序返回给定集合coll的最大元素。(注意:元素必须是同一种类型) |
max(Collection coll, Comparator comp) |
据比较器排序comp,返回给定集合coll中的最大元素。(注意:元素必须是同一种类型) |
min(Collection coll) |
根据自然顺序返回给定集合coll的最小元素。(注意:元素必须是同一种类型) |
min(Collection coll, Comparator comp) |
据比较器排序comp,返回给定集合coll中的最小元素。(注意:元素必须是同一种类型) |
reverse(List list) |
反转指定集合list中元素的顺序。 |
shuffle(List list) |
将集合中list中元素的随机打乱顺序,常常用来洗牌。 |
sort(List list) |
将list集合升序排序。(注意:元素必须是同一种类型) |
sort(List list, Comparator c) |
根据指定的比较器c对指定的集合list进行排序。(注意:元素必须是同一种类型) |
swap(List list, int i, int j) |
交换集合list中下标i和下标j的元素位置。 |
synchronizedList(List list) |
将list对象转换为线程安全的。 |
synchronizedMap(Map<K,V> m) |
将map对象转换为线程安全的。 |
synchronizedSet(Set s) |
将set对象转换为线程安全的。 |
ArrayList
ArrayList
类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。ArrayList
继承了 AbstractList
,并实现了 List
接口。
扩容底层是使用Arrays.copyOf
,在元素个数大于数组长度的时候进行扩容,扩容每次扩大到原长度的1.5倍,
// 导包 与 初始化
import java.util.ArrayList; // 引入 ArrayList 类
// E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
// objectName: 对象名。
ArrayList<E> objectName = new ArrayList<>(); // 初始化
常用方法:
方法 | 描述 |
---|---|
add() |
将元素插入到指定位置的 arraylist 中 |
addAll() |
添加集合中的所有元素到 arraylist 中 |
clear() |
删除 arraylist 中的所有元素 |
clone() |
复制一份 arraylist |
contains() |
判断元素是否在 arraylist |
get() |
通过索引值获取 arraylist 中的元素 |
indexOf() |
返回 arraylist 中元素的索引值 |
removeAll() |
删除存在于指定集合中的 arraylist 里的所有元素 |
remove() |
删除 arraylist 里的单个元素 |
size() |
返回 arraylist 里元素数量 |
isEmpty() |
判断 arraylist 是否为空 |
subList() |
截取部分 arraylist 的元素 |
set() |
替换 arraylist 中指定索引的元素 |
sort() |
对 arraylist 元素进行排序 |
toArray() |
将 arraylist 转换为数组 |
toString() |
将 arraylist 转换为字符串 |
ensureCapacity() |
设置指定容量大小的 arraylist |
lastIndexOf() |
返回指定元素在 arraylist 中最后一次出现的位置 |
retainAll() |
保留 arraylist 中在指定集合中也存在的那些元素 |
containsAll() |
查看 arraylist 是否包含指定集合中的所有元素 |
trimToSize() |
将 arraylist 中的容量调整为数组中的元素个数 |
removeRange() |
删除 arraylist 中指定索引之间存在的元素 |
replaceAll() |
将给定的操作内容替换掉数组中每一个元素 |
removeIf() |
删除所有满足特定条件的 arraylist 元素 |
forEach() |
遍历 arraylist 中每一个元素并执行特定操作 |
LinkedList
LinkedList
是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。链表可分为单向链表和双向链表。一个单向链表包含两个值:当前节点的值和一个指向下一个节点的链接。
// 导包 与 初始化
import java.util.LinkedList;
LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表
常用方法:
方法名 | 描述 |
---|---|
add(E e) |
链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
add(int index, E element) |
向指定位置插入元素。 |
addAll(Collection c) |
将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。 |
`addAll(int index, Collection c) | 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。 |
addFirst(E e) |
元素添加到头部。 |
addLast(E e) |
元素添加到尾部。 |
offer(E e) |
向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
offerFirst(E e) |
头部插入元素,返回是否成功,成功为 true,失败为 false。 |
offerLast(E e) |
尾部插入元素,返回是否成功,成功为 true,失败为 false。 |
clear() |
清空链表。 |
removeFirst() |
删除并返回第一个元素。 |
removeLast() |
删除并返回最后一个元素。 |
remove(Object o) |
删除某一元素,返回是否成功,成功为 true,失败为 false。 |
remove(int index) |
删除指定位置的元素。 |
poll() |
删除并返回第一个元素。 |
remove() |
删除并返回第一个元素。 |
contains(Object o) |
判断是否含有某一元素。 |
get(int index) |
返回指定位置的元素。 |
getFirst() |
返回第一个元素。 |
getLast() |
返回最后一个元素。 |
indexOf(Object o) |
查找指定元素从前往后第一次出现的索引。 |
lastIndexOf(Object o) |
查找指定元素最后一次出现的索引。 |
peek() |
返回第一个元素。 |
element() |
返回第一个元素。 |
peekFirst() |
返回头部元素。 |
peekLast() |
返回尾部元素。 |
set(int index, E element) |
设置指定位置的元素。 |
clone() |
克隆该列表。 |
descendingIterator() |
返回倒序迭代器。 |
size() |
返回链表元素个数。 |
listIterator(int index) |
返回从指定位置开始到末尾的迭代器。 |
toArray() |
返回一个由链表元素组成的数组。 |
toArray(T[] a) |
返回一个由链表元素转换类型而成的数组。 |
HashSet
HashSet
基于 HashMap
来实现的,实现了 Set
接口,是一个不允许有重复元素的集合。HashSet
是无序的,即不会记录插入的顺序,HashSet
允许有 null
值。
HashSet
不是线程安全的, 如果多个线程尝试同时修改 HashSet
,则最终结果是不确定的。 必须在多线程访问时显式同步对 HashSet
的并发访问。
// 导包 与 初始化
import java.util.HashSet;
HashSet<String> sites = new HashSet<String>();
常用方法:
方法 | 描述 |
---|---|
add(E e) |
如果指定的元素尚不存在,则将其添加到此集合中。 |
clear() |
从该集中删除所有元素。 |
clone() |
返回此 HashSet 实例的浅表副本:未克隆元素本身。 |
contains(Object o) |
如果此set包含指定的元素,则返回 true 。 |
isEmpty() |
如果此集合不包含任何元素,则返回 true 。 |
iterator() |
返回此set中元素的迭代器。 |
remove(Object o) |
如果存在,则从该集合中移除指定的元素。 |
size() |
返回此集合中的元素数(基数)。 |
spliterator() |
在此集合中的元素上创建late-binding和失败快速 Spliterator 。 |
LinkedHashSet
LinkedHashSet
是HashSet
的子类,是有序的HashSet
,通过链表完成。所以继承了HashSet
所有的方法
TreeSet
TreeSet
对元素进行排序,底层是基于TreeMap
来实现的,TreeMap底层基于红黑树(特殊的二叉树,左边叉值小,右边叉值大,有自平衡机制),存储的元素类型必须一样且元素类型的类必须实现Comparable
接口。
TreeSet
存在两种排序方式:
-
自然排序:元素类型必须实现了
Comparable
接口,且必须重写compareTo()
方法。 -
定制排序: 在创建
TreeSet
对象的时候,传入一个Comparator
接口的实现类,该实现类必须重写compare
方法。
构造方法:
-
TreeSet()
创建一个有自然排序功能的TreeSet
对象。 默认自然排序是升序。 -
TreeSet(Collection c)
构造一个包含指定集合中的元素的新树集,根据其元素的 自然排序进行排序 。 使用该构造方法,要求,集合参数c必须元素是同一种类型,且实现了Comparable
接口的。 -
TreeSet(Comparator comparator)
创建一个有定制排序功能的TreeSet对象。可以使用Comparator的实现类对象,也可以使用Comparator的匿名内部类。
常用方法:
方法 | 描述 |
---|---|
add(E e) |
如果指定的元素尚不存在,则将其添加到此集合中。 |
addAll(Collection<?extends E> c) |
将指定集合中的所有元素添加到此集合中。 |
ceiling(E e) |
返回此set中大于或等于给定元素的 null元素,如果没有这样的元素,则 null 。 |
clear() |
从该集中删除所有元素。 |
clone() |
返回此 TreeSet实例的浅表副本。 |
contains(Object o) |
如果此set包含指定的元素,则返回 true 。 |
descendingIterator() |
以降序返回此集合中元素的迭代器。 |
descendingSet() |
返回此set中包含的元素的逆序视图。 |
first() |
返回此集合中当前的第一个(最低)元素。 |
floor(E e) |
返回此set中小于或等于给定元素的最大元素,如果没有这样的元素,则 null 。 |
headSet(E toElement) |
返回此set的部分视图,其元素严格小于 toElement 。 |
headSet(E toElement, boolean inclusive) |
返回此set的部分视图,其元素小于(或等于,如果 inclusive为true) toElement 。 |
higher(E e) |
返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则 null 。 |
isEmpty() |
如果此集合不包含任何元素,则返回 true 。 |
iterator() |
以升序返回此集合中元素的迭代器。 |
last() |
返回此集合中当前的最后一个(最高)元素。 |
lower(E e) |
返回此集合中的最大元素严格小于给定元素,如果没有这样的元素,则 null 。 |
pollFirst() |
检索并删除第一个(最低)元素,如果此组为空,则返回 null 。 |
pollLast() |
检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 。 |
remove(Object o) |
如果存在,则从该集合中移除指定的元素。 |
size() |
返回此集合中的元素数(基数)。 |
spliterator() |
在此集合中的元素上创建late-binding和故障快速 Spliterator 。 |
subSet(E fromElement, E toElement) |
返回此set的部分视图,其元素范围从 fromElement (含)到 toElement (独占)。 |
tailSet(E fromElement) |
返回此set的部分视图,其元素大于或等于 fromElement 。 |
Map
Map
也是一种容器的接口,里面存储的是一对一对的数据,每添加一次,添加的是两个(一对)数据,一个映射(一个Map对象)不能包含重复的键,与Collection
并无关系;Collection
体系,存储在都是单个单个的数据,数据之间没有关系。
Map
的遍历方式:
-
如果只是获取所有一个值,使用
values()
方法 -
如果只是获取所有的key,使用
keySet()
方法 -
如果获取所有的key-value,使用
entrySet()
,不要用先通过keySet()
获取key,再用get()
获取具体的value,这样会导致二次查询,效率低下
Map m = new HashMap();
m.put("小明", 90);
m.put("小马", 60);
m.put("小郭", 60);
Set entrys = m.entrySet();
for (Object en : entrys) {
// 需要把en强制转成 Entry类型
Entry e = (Entry)en;
System.out.println(e.getKey()+"--"+e.getValue());
}
HashMap
基于hashCode()
,底层是Entry
键值对的数组,数组中装装的是键值对。从结构实现来讲,HashMap
是数组+链表+红黑树实现。
HashMap
会根据添加的key
的hashCode
值与当前数组的length
(默认是16)取模,而得到数组的下标,进而保存键值对,故HashMap
存储的数据是无序的,因为角标是计算得出而不是按顺序排列。
如果key
模length
后,得到的下标是相等的,就会发生哈希冲突,这时候再继续判断key
的equals
方法,如果equals
判断为true
,就会将原来的键值对覆盖,如果是false
,就会在该下标处的原来键值对后面形成链表,如果链表长度达到8个且元素总量大于64时,就形成红黑树。当删除键值对后剩余的数量小于等于6的时候,就重新将红黑树退化为链表。
构造方法:
-
HashMap()
构造一个空的HashMap
,默认初始容量(16)和默认负载系数(0.75)。容量16:是键值对的数组长度16
负载系数0.75:扩容机制是当容量达到75%的时候,开始扩容,就是创建新数组,复制元素。
-
HashMap(int initialCapacity)
创建空的HashMap
具有指定的初始容量initialCapacity
和默认负载因子(0.75)。 -
HashMap(int initialCapacity, float loadFactor)
构造一个空的HashMap
具有指定的初始容量和负载因子。 -
HashMap(Map m)
创建一个HashMap
对象,并且传入另一个Map
对象m
,这样先创建对象就有了与m
相同的数据
常用方法:
方法 | 描述 |
---|---|
putAll(Map m) |
将传入的Map作为参数,创建一个新的HashMap对象 |
get(Object key) |
根据key去获取value值,如果key不存在,则返回null |
remove(Object key) |
根据key删除当前map对象中的这一对键值对 |
remove(Object key, Object value) |
只有key和value都存在的时候,才能删除 |
replace(K key, V value) |
根据key替换为新的value的值 |
replace(K key, V oldValue, V newValue) |
只有当key和value都存在的情况下,才能替换为新的 newValue值 |
containsKey(Object key) |
判断当前map集合对象中是否包含这个key |
containsValue(Object value) |
判断当前map集合对象中是否包含这个value,包含则返回 true 。 |
clear() |
清除所有的键值对对象 |
isEmpty() |
判段当前map对象是否是空集合 。 |
size() |
获取当前Map键值对个数。 |
HashTable
与 HashMap
的区别:
-
HashMap
可以接受null
键值和值,而HashTable
则不能。 -
HashMap
去掉了Hashtable
的contains
方法,改成containsValue
和containsKey
。 -
Hashtable
继承自Dictionary
类,而HashMap
是Java1.2引进的interface Map
的一个实现。 -
最大的不同是,
Hashtable
的方法是Synchronize
的,而HashMap
不是,在多个线程访问Hashtable
时,不需要自己为它的方法实现同步,而**HashMap
就必须为之提供外同步**。 -
Hashtable
和HashMap
采用的hash/rehash
算法都大概一样,所以性能不会有很大的差异。
Properties
Properties
继承于 Hashtable
。表示一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。Properties
定义的实例变量,这个变量持有一个 Properties
对象相关的默认属性列表。
使用场景:
-
将内存中的数据写入到硬盘中;
-
将硬盘中的数据读取到内存中;
-
使用时需要使用
Properties
自己的方法,才能使key
和value
都是String
类型。
常用方法:
方法 | 描述 |
---|---|
String getProperty(String key) |
用指定的键在此属性列表中搜索属性。 |
String getProperty(String key, String defaultProperty) |
用指定的键在属性列表中搜索属性,defaultProperty为不存在时的提示内容。 |
void list(PrintStream streamOut) |
将属性列表输出到指定的输出流。 |
void list(PrintWriter streamOut) |
将属性列表输出到指定的输出流。 |
void load(InputStream streamIn) throws IOException |
从输入流中读取属性列表(键和元素对)。 |
Enumeration propertyNames( ) |
按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 |
Object setProperty(String key, String value) |
调用 Hashtable 的方法 put。 |
void store(OutputStream streamOut, String description) |
以适合使用 load(InputStream)方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 |
Properties pp = new Properties(); //获得一个Properties对象
pp.setProperty("XXXX", "OOOO"); //给Properties对象设置值
pp.setProperty("YYYY", "JJJJ");
System.out.println(pp.size());
System.out.println(pp);
System.out.println(pp.getProperty("XXXX")); //从Properties对象根据key获得值
PrintStream ps = new PrintStream("/qq.txt"); // 建立一个打印流与文件关联
pp.list(ps); // 将list方法的值持久化到文件中
FileInputStream fis = new FileInputStream("/easyexplore.link") // 建立一个文件输入流,与对应文件相关联
pp.load(fis); // load方法讲文件中的值加载到Properties对象中
System.out.println(pp);
String property = pp.getProperty("path"); // 获得Properties对象中的 “path” 值对应的属性
System.out.println(property);
泛型
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
规则限制:
- 泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
- 同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
- 泛型的类型参数可以有多个。
- 泛型的参数类型可以使用extends语句,例如
<T extends superclass>
。习惯上称为“有界类型”。 - 泛型的参数类型还可以是通配符类型。例如
<? extends Number>
表示最高可以传入的类型是Number及其子类类型
泛型类
一个类本质看成是一个通用的模板,在设计类的时候,其中的数据类型写一个符号,泛指所有的类型,但是不指具体的某种类型
当在使用模板来创建一个对象的时候可以指定自己的类型。
class Point<数据类型>{ // 表示在类声明了一个符号 数据类型,是一种泛指
数据类型 x;
数据类型 y;
}
泛型方法
就是把泛型类型的声明放在某个方法上面,只需将泛型参数列表置于返回值前,只能够本方法上或者内部可以使用这个符号,在调用方法的时候传入的实际参数为真实的类型。
注:在创建数组的时候,必须要知道具体类型的。
public static <T> T[] getArr(T[] arr){
T[] copyOf = (T[])Arrays.copyOf(arr, arr.length, arr.getClass());
Arrays.sort(copyOf);
return copyOf;
}