当前位置: 首页 > java>阅读正文

Java集合框架学习笔记

2021.11.23 朱丰华 1915 次 留下评论 16132字

集合是一种容器,存储的都是对象,对于基本类型可以使用它的包装类。

集合可以看作数组,但实际上两者相差甚远。主要原因在于:集合本身也是对象,它甚至(或者说完全)可以取代传统的实体类,整个项目中不使用实体类有时效率更高,对复杂的json以及数据库数据处理非常方便。

集合综合概述

集合的所有类,都在java.util包下

集合框架按照存储结构可以分为2大类:

单列集合Java.util.Collection
双列集合Java.util.Map

集合是灵活的,它的特点主要如下:

  • 无限制长度
  • 无限制类型
  • 集合有多种实现方式,适用于不同的使用场景

Collection集合

Collection 是单列集合类的根接口,它有 2 个重要的子接口集合,分别是

名称特点
list集合元素有序
元素可重复
有索引
set集合元素无序
元素不可重复
无索引

其常用子类关系如下:

单列集合Collection,通常用于取代数组

方法摘要
 booleanadd(E e)
          确保此 collection 包含指定的元素(可选操作)。
 booleanaddAll(Collection<? extends E> c)
          将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
 voidclear()
          移除此 collection 中的所有元素(可选操作)。
 booleancontains(Object o)
          如果此 collection 包含指定的元素,则返回 true。
 booleancontainsAll(Collection<?> c)
          如果此 collection 包含指定 collection 中的所有元素,则返回 true。
 booleanequals(Object o)
          比较此 collection 与指定对象是否相等。
 inthashCode()
          返回此 collection 的哈希码值。
 booleanisEmpty()
          如果此 collection 不包含元素,则返回 true。
 Iterator<E>iterator()
          返回在此 collection 的元素上进行迭代的迭代器。
 booleanremove(Object o)
          从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
 booleanremoveAll(Collection<?> c)
          移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
 booleanretainAll(Collection<?> c)
          仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。
 intsize()
          返回此 collection 中的元素数。
 Object[]toArray()
          返回包含此 collection 中所有元素的数组。
<T> T[]toArray(T[] a)
          返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。

Map集合

Map 是双列集合类的根接口,双列集合是 key-value 形式,其中key格式类型是任意的,不同于js的json格式,实际上它和js的map格式更接近,map集合是更灵活的实体类,它可以方便的增加删除元素(属性)。

其常用的子类继承关系如下:

嵌套类摘要
static interfaceMap.Entry<K,V>
          映射项(键-值对)。
方法摘要
 voidclear()
          从此映射中移除所有映射关系(可选操作)。
 booleancontainsKey(Object key)
          如果此映射包含指定键的映射关系,则返回 true。
 booleancontainsValue(Object value)
          如果此映射将一个或多个键映射到指定值,则返回 true。
 Set<Map.Entry<K,V>>entrySet()
          返回此映射中包含的映射关系的 Set 视图。
 booleanequals(Object o)
          比较指定的对象与此映射是否相等。
 Vget(Object key)
          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
 inthashCode()
          返回此映射的哈希码值。
 booleanisEmpty()
          如果此映射未包含键-值映射关系,则返回 true。
 Set<K>keySet()
          返回此映射中包含的键的 Set 视图。
 Vput(K key, V value)
          将指定的值与此映射中的指定键关联(可选操作)。
 voidputAll(Map<? extends K,? extends V> m)
          从指定映射中将所有映射关系复制到此映射中(可选操作)。
 Vremove(Object key)
          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
 intsize()
          返回此映射中的键-值映射关系数。
 Collection<V>values()
          返回此映射中包含的值的 Collection 视图。

集合转字符串

无论是Collection集合,还是Map集合,都重写了toString()方法。

Collection集合为空时,显示[ ],这和数组是一致的。

Map集合为空时,显示{ },这和普通对象重写的toString()是一致的。

在这里,并不是为了讨论toString,具体想表达的是:Collection更接近数组,而Map更接近对象。集合是面向对象的一些弥补方案,面向对象思想虽好,但在java中不够灵活,而集合弥补了这方面的缺陷,集合是java重要的组成部分。

List接口

List 接口是 Collection 重要的子接口之一,List接口中有很多通用方法

List 接口有如下3个特点

  1. 有序的集合,存储和取出是一致的(存储123 取出123)
  2. 有索引,附带了一些索引的方法
  3. 允许存储重复的元素

ArrayList对象

ArrayList 是 List 的一个常用实现类,基于数组。

方法摘要
 booleanadd(E e)
          将指定的元素添加到此列表的尾部。
 voidadd(int index, E element)
          将指定的元素插入此列表中的指定位置。
 booleanaddAll(Collection<? extends E> c)
          按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
 booleanaddAll(int index, Collection<? extends E> c)
          从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
 voidclear()
          移除此列表中的所有元素。
 Objectclone()
          返回此 ArrayList 实例的浅表副本。
 booleancontains(Object o)
          如果此列表中包含指定的元素,则返回 true。
 voidensureCapacity(int minCapacity)
          如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
 Eget(int index)
          返回此列表中指定位置上的元素。
 intindexOf(Object o)
          返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
 booleanisEmpty()
          如果此列表中没有元素,则返回 true
 intlastIndexOf(Object o)
          返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
 Eremove(int index)
          移除此列表中指定位置上的元素。
 booleanremove(Object o)
          移除此列表中首次出现的指定元素(如果存在)。
protected  voidremoveRange(int fromIndex, int toIndex)
          移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
 Eset(int index, E element)
          用指定的元素替代此列表中指定位置上的元素。
 intsize()
          返回此列表中的元素数。
 Object[]toArray()
          按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。
<T> T[]toArray(T[] a)
          按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
 voidtrimToSize()
          将此 ArrayList 实例的容量调整为列表的当前大小。

LinkedList对象

LinkedList 是List的一个实现类,基于链表的双端队列的集合。

LinkedList 有很多基于首尾两端操作的方法。

方法摘要
 booleanadd(E e)
          将指定元素添加到此列表的结尾。
 voidadd(int index, E element)
          在此列表中指定的位置插入指定的元素。
 booleanaddAll(Collection<? extends E> c)
          添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。
 booleanaddAll(int index, Collection<? extends E> c)
          将指定 collection 中的所有元素从指定位置开始插入此列表。
 voidaddFirst(E e)
          将指定元素插入此列表的开头。
 voidaddLast(E e)
          将指定元素添加到此列表的结尾。
 voidclear()
          从此列表中移除所有元素。
 Objectclone()
          返回此 LinkedList 的浅表副本。
 booleancontains(Object o)
          如果此列表包含指定元素,则返回 true。
 Iterator<E>descendingIterator()
          返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。
 Eelement()
          获取但不移除此列表的头(第一个元素)。
 Eget(int index)
          返回此列表中指定位置处的元素。
 EgetFirst()
          返回此列表的第一个元素。
 EgetLast()
          返回此列表的最后一个元素。
 intindexOf(Object o)
          返回此列表中首次出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
 intlastIndexOf(Object o)
          返回此列表中最后出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
 ListIterator<E>listIterator(int index)
          返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。
 booleanoffer(E e)
          将指定元素添加到此列表的末尾(最后一个元素)。
 booleanofferFirst(E e)
          在此列表的开头插入指定的元素。
 booleanofferLast(E e)
          在此列表末尾插入指定的元素。
 Epeek()
          获取但不移除此列表的头(第一个元素)。
 EpeekFirst()
          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
 EpeekLast()
          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
 Epoll()
          获取并移除此列表的头(第一个元素)
 EpollFirst()
          获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
 EpollLast()
          获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
 Epop()
          从此列表所表示的堆栈处弹出一个元素。
 voidpush(E e)
          将元素推入此列表所表示的堆栈。
 Eremove()
          获取并移除此列表的头(第一个元素)。
 Eremove(int index)
          移除此列表中指定位置处的元素。
 booleanremove(Object o)
          从此列表中移除首次出现的指定元素(如果存在)。
 EremoveFirst()
          移除并返回此列表的第一个元素。
 booleanremoveFirstOccurrence(Object o)
          从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。
 EremoveLast()
          移除并返回此列表的最后一个元素。
 booleanremoveLastOccurrence(Object o)
          从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。
 Eset(int index, E element)
          将此列表中指定位置的元素替换为指定的元素。
 intsize()
          返回此列表的元素数。
 Object[]toArray()
          返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组。
<T> T[]toArray(T[] a)
          返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组;返回数组的运行时类型为指定数组的类型。

Vector对象

Vector 是线程同步的 List 接口实现类,仍然基于数组。

Vector 的效率比 ArrayList 更慢,主要特点是线程安全,而ArrayList,LinkedList都是线程不安全的。

此类中,基本没有太多特有的方法,它的方法和List接口是相差不大的。文档传送门:Vector (Java 2 Platform SE 6)

由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失败的:如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就完全失败,而不是冒着在将来不确定的时间任意发生不确定行为的风险。Vector 的 elements 方法返回的 Enumeration 不是 快速失败的。

注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测 bug。

Set接口

Set 接口是 Collection 的另一个重要的子接口

Set 接口有如下 3 个特点

  • 无序的集合
  • 没有索引
  • 不允许存储重复元素

它的底层是哈希表(由数组和二叉树实现),故无序,且不允许重复

HashSet对象

hashset是 set 的子类实现类,它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。

HashSet空参构造时:构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。

方法摘要
 booleanadd(E e)
          如果此 set 中尚未包含指定元素,则添加指定元素。
 voidclear()
          从此 set 中移除所有元素。
 Objectclone()
          返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。
 booleancontains(Object o)
          如果此 set 包含指定元素,则返回 true。
 booleanisEmpty()
          如果此 set 不包含任何元素,则返回 true。
 Iterator<E>iterator()
          返回对此 set 中元素进行迭代的迭代器。
 booleanremove(Object o)
          如果指定元素存在于此 set 中,则将其移除。
 intsize()
          返回此 set 中的元素的数量(set 的容量)。

LinkedHashSet对象

此类是HashSet的子类,由于加入了链表,所以它实际是有序的。

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序 受在 set 中重新插入的 元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。)官方文档传送门:LinkedHashSet (Java 2 Platform SE 6)

Iterator迭代器

Iterator 是一个接口类,用于遍历 Collection 集合

该类是 Collection 的父类,可以通过 Collection 获得 Iterator

实现了该接口的对象,都可以使用 迭代器遍历

1.导包

import java.util.Iterator;

2.构造方法

接口类无法直接创建,可以使用多态创建

//先创建Collection集合
Collection<String> coll = new ArrayList<>();
//使用Collection对象的 iterator 方法获取
Iterator<String> iterator = coll.iterator();

3.方法

1.返回下一个元素

iterator.next();

2.判断是否有下一个元素

iterator.hasNext();

4.简单使用,遍历 Collection 集合

Collection<String> coll = new ArrayList<>();
coll.add("hello");
coll.add("world");

//添加数据后获取迭代器,反过来会报错
Iterator<String> iterator = coll.iterator();
 
while(iterator.hasNext()){
	  String s = iterator.next();
	  System.out.println(s);  
	}

foreach循环

foreach 循环是 jdk5 推出的新特性,可以遍历数组和 Collection 集合

foreach 遍历数组 和 Collection 非常方便,是迭代器的简化写法

1.语法

for(变量类型 变量名: 变量对象){
  包含操作变量的语句体;
}

2.基本实例

遍历数组对象 a ,定义一个同数组元素类型的变量 x,

就可以在语句体中,x 就是每次遍历的数组元素

int[] a = {1,2,3,4,5};
for(int x: a) {
	System.out.print(x);
}
// 输出内容: 12345

它和for循环是不一样的,但是后来并不仅限于实现了Iterator接口的对象能使用,数组也可以使用foreach,就像上面的例子。

注意这里的foreach,不是指Stream流的foreach,不要混淆。

泛型的使用

1.泛型基本概念

当存储的类型比较大,比如是 Object 类型时,可以使用泛型向下指定

配合 Object, 泛型可以很方便的指定某种数据类型

官方并没有对泛型准确的定义,这里做一个定义

泛型的概念:泛型是限定数据类型的一种手段

2.泛型类的定义

在类后面加一个<E>,并且把属性和方法定义为 E 类型

在创建类的时候,确定E的数据类型,如果不写,默认是 Object

public class GeneClass<E>{
  private E name;
  public E getName(){
    return name;
  }
  public void setName(E name){
    this.name = name;
  }
}

3.泛型方法的定义

在返回值类型前,在static 后的位置,加上<E>

在调用方法时,确定传递的数据类型,默认是 Object

public <M> void method1(M m){
  System.out.println(m);
}
public static <S> void method2(S s){
  System.out.println(s);
}

4.泛型接口的定义

分别有接口类本身 和 实现类的泛型定义

//接口类本身的定义
public interface  Iterator<E>{
  E next();
}
//实现类在实现时指定泛型
public final class Scanner implements Iterator<String>{
  public String next(){}
}

//实现类本身定义和使用接口的泛型,此时必须使用相同的字母
public class ArrayList<E> implements List<E>{
  public boolean add(E e){}
  public E get(int index){}
}

5.泛型的上限和下限限定

使用 ? extends E ,表示 E 是父类,? 只能是子类(或者它本身)

使用 ? super E ,表示 ? 是父类(或者它本身),无法使用子类

//泛型的上限?必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
//泛型的下限?必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}

方法可变参数

可变参数是 jdk5 推出的新特性

可变参数类似数组,但不是直接传递数组对象,而是数组元素

1.语法格式

参数类型...变量名

可变参数可以传递空参数,参数类型可以是任意类型,包括Object

可变参数只能是最后一个参数

2.例子

public static void main(String[] args) {
	say(1);
 //可变参数为空
	say(2,3,4,5);
}
public static void say(int i,int...is) {
//第一个是正常参数,最后一个是可变参数
	for(int x:is) {
		System.out.println(x);
	}
}

此方法定义了一个 2 个参数的方法,其中可变参数必须是最后一个

在一个方法中,无法传递多个可变参数。

Collections工具类

单列集合本身仍有一些缺陷,比如无法排序。

Collections类完全由在 collection 上进行操作或返回 collection 的静态方法组成。它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。

以下仅给出几个方法示例,更多请参考官方文档:Collections (Java 2 Platform SE 6)

1.添加多个元素

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"a","c","b");
System.out.println(list);

2.元素排序

//排序方式1 ,自定义对象需要实现 Comparable 接口
Collections.sort(list);//()
System.out.println(list);
//排序方式2 ,使用 Comparator 对象
ArrayList<Integer> list2 = new ArrayList<>();
Collections.sort(list2, new Comparator<Integer>() {
	@Override
	public int compare(Integer o1, Integer o2) {
		// TODO Auto-generated method stub
		return o1-o2;
	}
});

3.打乱元素

Collections.shuffle(list);
System.out.println(list);

Map接口

Map 集合是一个双列集合,包含1个 key, 1个 value

Map 集合中的元素, key, value 可以是相同,或不同类型的

key 是不允许重复的, value 允许重复

key 与 value 是一一对应的,但value可以是一个集合,也就是Map集合可以嵌套,当然Collection集合也是可以嵌套的。

Map常用方法演示

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

1.添加元素

//1.添加元素
String m1 = map.put("水浒传","施耐庵");
map.put("三国演义","罗贯中");
map.put("三国演义2","罗贯中");
String m3 = map.put("水浒传","施耐庵2");// key 重复时,会自动覆盖
//添加的 key 为空时,返回null,否则返回 value
System.out.println("m1:"+m1+",m3:"+m3);
System.out.println(map);

2.删除元素

//2.删除元素
String s4 = map.remove("西游记"); //没有此 key ,返回 null
String s5 = map.remove("水浒传"); //删除水浒传,返回被删除的值
System.out.println("s4:"+s4+",s5:"+s5);
System.out.println(map);

3.获取 value

//3.获取元素
String s6 = map.get("水浒传");  //没有此 key,返回 null
String s7 = map.get("三国演义");   //存在此 key,返回 value
System.out.println("s6:"+s6+",s7:"+s7);

4.查询是否包含元素

//4.查询是否包含元素
boolean b1 = map.containsKey("红楼梦"); //没有此 key,返回 null
boolean b2 = map.containsKey("三国演义"); //存在此 key,返回 value
System.out.println("b1:"+b1+",b2:"+b2);

5.遍历 map 集合

//5.1 -> keySet 遍历
Set<String> set = map.keySet();  //1.得到所有的 key
for(String key : set){  //2.使用增强 for 遍历 key
  String value = map.get(key);  //3.使用 get 方法获取 value
  System.out.println(key+"="+value);
}
//5.2 -> entrySet 遍历
Set<Map.Entry<String,String>> set2 = map.entrySet(); //1.获取所有的 entry 对象
for(Map.Entry<String,String> entry : set2){ //2.使用增强 for 遍历 entry
  String key = entry.getKey();  //3.取得 key
  String value = entry.getValue(); //4.取得 value
  System.out.println(key+"="+value);
}

hashMap对象

基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

方法摘要
 voidclear()
          从此映射中移除所有映射关系。
 Objectclone()
          返回此 HashMap 实例的浅表副本:并不复制键和值本身。
 booleancontainsKey(Object key)
          如果此映射包含对于指定键的映射关系,则返回 true。
 booleancontainsValue(Object value)
          如果此映射将一个或多个键映射到指定值,则返回 true。
 Set<Map.Entry<K,V>>entrySet()
          返回此映射所包含的映射关系的 Set 视图。
 Vget(Object key)
          返回指定键所映射的值;如果对于该键来说,此映射不包含任何映射关系,则返回 null
 booleanisEmpty()
          如果此映射不包含键-值映射关系,则返回 true。
 Set<K>keySet()
          返回此映射中所包含的键的 Set 视图。
 Vput(K key, V value)
          在此映射中关联指定值与指定键。
 voidputAll(Map<? extends K,? extends V> m)
          将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射中所有键的所有映射关系。
 Vremove(Object key)
          从此映射中移除指定键的映射关系(如果存在)。
 intsize()
          返回此映射中的键-值映射关系数。
 Collection<V>values()
          返回此映射所包含的值的 Collection 视图。

LinkedHashMap对象

此类是HashMap的子类,它与HashMap最大的区别是,LinkedHashMap是有序的,而HashMap无序。

Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。注意,如果在映射中重新插入 键,则插入顺序不受影响。(如果在调用 m.put(k, v) 前 m.containsKey(k) 返回了 true,则调用时会将键 k 重新插入到映射 m 中。)

它的方法和父类相差不大,可参考官方文档:LinkedHashMap (Java 2 Platform SE 6)

Hashtable对象

此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。

为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。

此外,它是线程安全的。

方法摘要
 voidclear()
          将此哈希表清空,使其不包含任何键。
 Objectclone()
          创建此哈希表的浅表副本。
 booleancontains(Object value)
          测试此映射表中是否存在与指定值关联的键。
 booleancontainsKey(Object key)
          测试指定对象是否为此哈希表中的键。
 booleancontainsValue(Object value)
          如果此 Hashtable 将一个或多个键映射到此值,则返回 true。
 Enumeration<V>elements()
          返回此哈希表中的值的枚举。
 Set<Map.Entry<K,V>>entrySet()
          返回此映射中包含的键的 Set 视图。
 booleanequals(Object o)
          按照 Map 接口的定义,比较指定 Object 与此 Map 是否相等。
 Vget(Object key)
          返回指定键所映射到的值,如果此映射不包含此键的映射,则返回 null. 更确切地讲,如果此映射包含满足 (key.equals(k)) 的从键 k 到值 v 的映射,则此方法返回 v;否则,返回 null
 inthashCode()
          按照 Map 接口的定义,返回此 Map 的哈希码值。
 booleanisEmpty()
          测试此哈希表是否没有键映射到值。
 Enumeration<K>keys()
          返回此哈希表中的键的枚举。
 Set<K>keySet()
          返回此映射中包含的键的 Set 视图。
 Vput(K key, V value)
          将指定 key 映射到此哈希表中的指定 value
 voidputAll(Map<? extends K,? extends V> t)
          将指定映射的所有映射关系复制到此哈希表中,这些映射关系将替换此哈希表拥有的、针对当前指定映射中所有键的所有映射关系。
protected  voidrehash()
          增加此哈希表的容量并在内部对其进行重组,以便更有效地容纳和访问其元素。
 Vremove(Object key)
          从哈希表中移除该键及其相应的值。
 intsize()
          返回此哈希表中的键的数量。
 StringtoString()
          返回此 Hashtable 对象的字符串表示形式,其形式为 ASCII 字符 “, ” (逗号加空格)分隔开的、括在括号中的一组条目。
 Collection<V>values()
          返回此映射中包含的键的 Collection 视图。

Properties对象

一个重要的集合类,通常用作配置文件,继承于Hashtable。

Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。

因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。类似地,如果在“不安全”的 Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。

这意味着,Properties应该作为配置文件类使用,而不是用作一般的集合,它的 keyvalue 都应该是字符串。

创建Properties对象

Properties p = new Properties();

1.添加数据

p.setProperty("张三","168");
p.setProperty("李四","175");
p.setProperty("王五","188");

2.获取 value

String v = p.getProperty("张三");
System.out.println(v);

3.遍历

Set<String> set = p.stringPropertyNames();
for(String key : set){
  String value = p.getProperty(key);
  System.out.println(key+"="+value);
}

4.写入到文件

// p.store(流,注释),
// 对于2种流,OutputStream不能写中文,Writer可以中文,
// 对于注释,默认Unicode编码,系统默认gbk,写中文会乱码,一般写英文或空字符串
// new FileWriter 会有异常,需要捕获或抛出
try {
	p.store(new FileWriter("D:\\a.txt"),"");
 //写到D盘a.txt,注释为空串
} catch (IOException e) {
	e.printStackTrace();
 //如果有异常,打印异常信息
}

5.读取文件中的 Properties 信息

// p.load(流),对于流, InputStream 不能读取中文,Reader可以中文
Properties p = new Properties();
try {
	p.load(new FileReader("D:\\a.txt"));
  //从D盘a.txt读取
}catch(IOException e) {
	e.printStackTrace();
}
Set<String> set = p.stringPropertyNames();
  //遍历输出Properties集合
for(String key : set){
  String value = p.getProperty(key);
  System.out.println(key+"="+value);
}

Properties 用作加载配置文件时,通常是 .properties 后缀

Properties 配置文件的注释,是 #

Properties 配置文件,每一行仅写一条数据

Properties 配置文件,每行中的 key, value 可以用 = , 空格等隔开

Properties 配置文件,每行中的数据,默认是字符串,无需加 “”

集合的of方法

对于jdk9及以上版本,可以使用of方法。

对于 List , Set , Map 接口,提供了一个静态的 of 添加元素方法

只使用于接口本身,不使用于实现类

当元素个数确定时,才可使用此方法,再次增删元素报错。此方法是用于集合快速取代普通对象而设计的,快速得到一个元素确定的集合。

对于 Set ,Map 不能有重复元素。

1.导包

import java.util.List;

2.使用 of 添加元素并构造对象

List<String> list = List.of("a","b","c");
System.out.println(list); // [a, b, c]

这时,无法添删元素,否则报错。

本篇完,还有疑问?留下评论吧

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注