学习笔记08——Java基础(四)

本文详细介绍了Java基础中的集合框架,包括Collection接口下的List接口(LinkedList、ArrayList、Vector)和Set接口(HashSet),以及Map接口的HashMap、HashTable和TreeMap。此外,还讲解了Object类的基本概念、泛型的应用,以及序列化的作用和步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、集合

Java集合类存放在java.util包中,是一个用来存放对象的容器。

  • 集合只能存放对象,基本数据类型会自动转换成对应的引用类型。
  • 集合存放的都是对象的引用,而非对象本身,对象本身还是放在堆内存中。
  • 集合可以存放不同类型,不限数量的数据类型。

集合框架如下:

(一)、Collection接口

1、List接口

(1)LinkedList(链表)

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。

链表分类:

  • 单向链表

  • 双向链表

LinkedList的使用场景:

  • 需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

LinkedList实现的接口:

  • LinkedList 继承了 AbstractSequentialList 类。
  • LinkedList 实现了 Queue 接口,可作为队列使用。
  • LinkedList 实现了 List 接口,可进行列表的相关操作。
  • LinkedList 实现了 Deque 接口,可作为队列使用。
  • LinkedList 实现了 Cloneable 接口,可实现克隆。
  • LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

常用方法:

方法描述
public boolean add(E e)链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public void add(int index, E element)向指定位置插入元素。
public boolean addAll(Collection c)将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。
public boolean addAll(int index, Collection c)将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。
public void addFirst(E e)元素添加到头部。
public void addLast(E e)元素添加到尾部。
public boolean offer(E e)向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public boolean offerFirst(E e)头部插入元素,返回是否成功,成功为 true,失败为 false。
public boolean offerLast(E e)尾部插入元素,返回是否成功,成功为 true,失败为 false。
public void clear()清空链表。
public E removeFirst()删除并返回第一个元素。
public E removeLast()删除并返回最后一个元素。
public boolean remove(Object o)删除某一元素,返回是否成功,成功为 true,失败为 false。
public E remove(int index)删除指定位置的元素。
public E poll()删除并返回第一个元素。
public E remove()删除并返回第一个元素。
public boolean contains(Object o)判断是否含有某一元素。
public E get(int index)返回指定位置的元素。
public E getFirst()返回第一个元素。
public E getLast()返回最后一个元素。
public int indexOf(Object o)查找指定元素从前往后第一次出现的索引。
public int lastIndexOf(Object o)查找指定元素最后一次出现的索引。
public E peek()返回第一个元素。
public E element()返回第一个元素。
public E peekFirst()返回头部元素。
public E peekLast()返回尾部元素。
public E set(int index, E element)设置指定位置的元素。
public Object clone()克隆该列表。
public Iterator descendingIterator()返回倒序迭代器。
public int size()返回链表元素个数。
public ListIterator listIterator(int index)返回从指定位置开始到末尾的迭代器。
public Object[] toArray()返回一个由链表元素组成的数组。
public T[] toArray(T[] a)返回一个由链表元素转换类型而成的数组。

示例:

package test1;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class TestLinkedList {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites);
        // 使用 addFirst() 在头部添加元素
        sites.addFirst("Wiki");
        System.out.println(sites);
        // 使用 addLast() 在尾部添加元素
        sites.addLast("Wiki");
        System.out.println(sites);
        // 使用 removeFirst() 移除头部元素
        sites.removeFirst();
        System.out.println(sites);
        // 使用 removeLast() 移除尾部元素
        sites.removeLast();
        System.out.println(sites);
        // 使用 getFirst() 获取头部元素
        System.out.println(sites.getFirst());
        // 使用 getLast() 获取尾部元素
        System.out.println(sites.getLast());
        //删除并返回第一个元素
        System.out.println(sites.poll());
        System.out.println(sites.remove());
        //判断是否含有某一元素
        System.out.println(sites.contains("Google"));
        //返回第一个元素
        System.out.println(sites.peek());
        System.out.println(sites.element());
        //设置指定位置的元素
        System.out.println(sites.set(0,"test"));
        //遍历的四种方式
        //(1)使用迭代器遍历
        Iterator iterator = sites.iterator();
        while (iterator.hasNext()) System.out.print (iterator.next()+"  ");
        //(2)使用列表迭代器遍历
        System.out.println();
        ListIterator<String> listIterator = sites.listIterator();
        while(listIterator.hasNext()) System.out.print(listIterator.next() + "  ");
        //(3)使用size()和get()方法遍历 (for循环)
        System.out.println();
        for(int i = 0; i < sites.size(); i++) System.out.print(sites.get(i) + "  ");
        //使用增强for遍历
        System.out.println();
        for(String str : sites) System.out.print(str + "  ");
    }
}

输出结果:
[Google, Runoob, Taobao, Weibo]
[Wiki, Google, Runoob, Taobao, Weibo]
[Wiki, Google, Runoob, Taobao, Weibo, Wiki]
[Google, Runoob, Taobao, Weibo, Wiki]
[Google, Runoob, Taobao, Weibo]
Google
Weibo
Google
Runoob
false
Taobao
Taobao
Taobao
test  Weibo  
test  Weibo  
test  Weibo  
test  Weibo  

(2)ArrayList

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。ArrayList 继承了 AbstractList ,并实现了 List 接口。

使用场景:

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。

实现的接口:

  • List接口
  • RandomAccess接口
  • Cloneable接口
  • Serializable接口
  • 继承了AbstractList类

常用方法:

方法描述
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 中每一个元素并执行特定操作

示例:

public class TestArrayList {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites);
        // 访问第二个元素
        System.out.println(sites.get(1));
        // 第一个参数为索引位置,第二个为要修改的值
        sites.set(2, "Wiki");
        System.out.println(sites);
        //删除第四个元素
        sites.remove(3);
        System.out.println(sites);
        //计算 ArrayList 中的元素数量
        System.out.println(sites.size());
        //字母排序
        sites.add("Weibo");
        sites.add("Google");
        Collections.sort(sites);
        System.out.println(sites);
        //将 arraylist 转换为数组
        System.out.println(sites.toArray());
        //将 arraylist 转换为字符串
        System.out.println(sites.toString());
        //返回指定元素在 arraylist 中最后一次出现的位置
        System.out.println(sites.lastIndexOf("Google"));
        //查看 arraylist 是否包含指定元素
        System.out.println(sites.contains("Weibo"));
        //将给定的操作内容替换掉数组中每一个元素
        sites.replaceAll(String::toUpperCase);
        System.out.println(sites);
        //遍历
        //(1)使用迭代器遍历
        Iterator iterator = sites.iterator();
        while (iterator.hasNext()) System.out.print (iterator.next()+"  ");
        //(2)使用列表迭代器遍历
        System.out.println();
        ListIterator<String> listIterator = sites.listIterator();
        while(listIterator.hasNext()) System.out.print(listIterator.next() + "  ");
        //(3)使用size()和get()方法遍历 (for循环)
        System.out.println();
        for(int i = 0; i < sites.size(); i++) System.out.print(sites.get(i) + "  ");
        //使用增强for遍历
        System.out.println();
        for(String str : sites) System.out.print(str + "  ");
    }
}

运行结果:
[Google, Runoob, Taobao, Weibo]
Runoob
[Google, Runoob, Wiki, Weibo]
[Google, Runoob, Wiki]
3
[Google, Google, Runoob, Weibo, Wiki]
[Ljava.lang.Object;@7f31245a
[Google, Google, Runoob, Weibo, Wiki]
1
true
[GOOGLE, GOOGLE, RUNOOB, WEIBO, WIKI]
GOOGLE  GOOGLE  RUNOOB  WEIBO  WIKI  
GOOGLE  GOOGLE  RUNOOB  WEIBO  WIKI  
GOOGLE  GOOGLE  RUNOOB  WEIBO  WIKI  
GOOGLE  GOOGLE  RUNOOB  WEIBO  WIKI  
Process finished with exit code 0

(3)Vector

Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:

  • Vector 是同步访问的。
  • Vector 包含了许多传统的方法,这些方法不属于集合框架。

Vector 类支持 4 种构造方法:

  • 第一种构造方法创建一个默认的向量,默认大小为 10:
Vector()
  • 第二种构造方法创建指定大小的向量。
Vector(int size)
  • 第三种构造方法创建指定大小的向量,并且增量用 incr 指定。增量表示向量每次增加的元素数目。
Vector(int size,int incr)
  • 第四种构造方法创建一个包含集合 c 元素的向量:
Vector(Collection c)

常用方法:

序号方法描述
1void add(int index, Object element) 
 在此向量的指定位置插入指定的元素。
2boolean add(Object o) 
 将指定元素添加到此向量的末尾。
3boolean addAll(Collection c) 
将指定 Collection 中的所有元素添加到此向量的末尾,按照指定 collection 的迭代器所返回的顺序添加这些元素。
4boolean addAll(int index, Collection c) 
在指定位置将指定 Collection 中的所有元素插入到此向量中。
5void addElement(Object obj) 
 将指定的组件添加到此向量的末尾,将其大小增加 1。
6int capacity() 
返回此向量的当前容量。
7void clear() 
从此向量中移除所有元素。
8Object clone() 
返回向量的一个副本。
9boolean contains(Object elem) 
如果此向量包含指定的元素,则返回 true。
10boolean containsAll(Collection c) 
如果此向量包含指定 Collection 中的所有元素,则返回 true。
11void copyInto(Object[] anArray) 
 将此向量的组件复制到指定的数组中。
12Object elementAt(int index) 
返回指定索引处的组件。
13Enumeration elements() 
返回此向量的组件的枚举。
14void ensureCapacity(int minCapacity) 
增加此向量的容量(如有必要),以确保其至少能够保存最小容量参数指定的组件数。
15boolean equals(Object o) 
比较指定对象与此向量的相等性。
16Object firstElement() 
返回此向量的第一个组件(位于索引 0) 处的项)。
17Object get(int index) 
返回向量中指定位置的元素。
18int hashCode() 
返回此向量的哈希码值。
19int indexOf(Object elem) 
 返回此向量中第一次出现的指定元素的索引,如果此向量不包含该元素,则返回 -1。
20int indexOf(Object elem, int index) 
 返回此向量中第一次出现的指定元素的索引,从 index 处正向搜索,如果未找到该元素,则返回 -1。
21void insertElementAt(Object obj, int index) 
将指定对象作为此向量中的组件插入到指定的 index 处。
22boolean isEmpty() 
测试此向量是否不包含组件。
23Object lastElement() 
返回此向量的最后一个组件。
24int lastIndexOf(Object elem) 
 返回此向量中最后一次出现的指定元素的索引;如果此向量不包含该元素,则返回 -1。
25int lastIndexOf(Object elem, int index) 
返回此向量中最后一次出现的指定元素的索引,从 index 处逆向搜索,如果未找到该元素,则返回 -1。
26Object remove(int index) 
 移除此向量中指定位置的元素。
27boolean remove(Object o) 
移除此向量中指定元素的第一个匹配项,如果向量不包含该元素,则元素保持不变。
28boolean removeAll(Collection c) 
从此向量中移除包含在指定 Collection 中的所有元素。
29void removeAllElements() 
从此向量中移除全部组件,并将其大小设置为零。
30boolean removeElement(Object obj) 
从此向量中移除变量的第一个(索引最小的)匹配项。
31void removeElementAt(int index) 
删除指定索引处的组件。
32protected void removeRange(int fromIndex, int toIndex)
从此 List 中移除其索引位于 fromIndex(包括)与 toIndex(不包括)之间的所有元素。
33boolean retainAll(Collection c) 
在此向量中仅保留包含在指定 Collection 中的元素。
34Object set(int index, Object element)
 用指定的元素替换此向量中指定位置处的元素。
35void setElementAt(Object obj, int index) 
将此向量指定 index 处的组件设置为指定的对象。
36void setSize(int newSize) 
 设置此向量的大小。
37int size() 
 返回此向量中的组件数。
38List subList(int fromIndex, int toIndex) 
返回此 List 的部分视图,元素范围为从 fromIndex(包括)到 toIndex(不包括)。
39Object[] toArray()
 返回一个数组,包含此向量中以恰当顺序存放的所有元素。
40Object[] toArray(Object[] a) 
返回一个数组,包含此向量中以恰当顺序存放的所有元素;返回数组的运行时类型为指定数组的类型。
41String toString() 
返回此向量的字符串表示形式,其中包含每个元素的 String 表示形式。
42void trimToSize() 
  对此向量的容量进行微调,使其等于向量的当前大小。

示例:

public class TestVector {
    public static void main(String args[]) {
        // initial size is 3, increment is 2(创建一个大小为3,当快满时按2个元素大小的扩容向量)
        Vector v = new Vector(3, 2);
        System.out.println("Initial size: " + v.size());
        System.out.println("Initial capacity: " +
                v.capacity());
        v.addElement(new Integer(1));
        v.addElement(new Integer(2));
        v.addElement(new Integer(3));
        v.addElement(new Integer(4));
        //向量大小
        System.out.println("Capacity after four additions: " +
                v.capacity());

        //将指定的组件添加到此向量的末尾,将其大小增加 1。
        v.addElement(new Double(5.45));
        System.out.println("Current capacity: " +
                v.capacity());
        v.addElement(new Double(6.08));
        v.addElement(new Integer(7));
        System.out.println("Current capacity: " +
                v.capacity());
        v.addElement(new Float(9.4));
        v.addElement(new Integer(10));
        System.out.println("Current capacity: " +
                v.capacity());
        v.addElement(new Integer(11));
        v.addElement(new Integer(12));
        //输出第一个向量
        System.out.println("First element: " +
                (Integer)v.firstElement());
        //输出最后一个向量
        System.out.println("Last element: " +
                (Integer)v.lastElement());
        //是否包含3
        if(v.contains(new Integer(3)))
            System.out.println("Vector contains 3.");
        // enumerate the elements in the vector.
        //返回此向量的组件的枚举
        Enumeration vEnum = v.elements();
        System.out.println("\nElements in vector:");
        while(vEnum.hasMoreElements())
            System.out.print(vEnum.nextElement() + " ");
        System.out.println();
    }
}


运行结果:
Initial size: 0
Initial capacity: 3
Capacity after four additions: 5
Current capacity: 5
Current capacity: 7
Current capacity: 9
First element: 1
Last element: 12
Vector contains 3.

Elements in vector:
1 2 3 4 5.45 6.08 7 9.4 10 11 12 

2、Set接口

(1)HashSet

特点:

  • HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
  • HashSet 允许有 null 值。
  • HashSet 是无序的,即不会记录插入的顺序。
  • 没有索引,没有带索引的方法,也不能使用普通的for遍历
  • HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
  • 底层是一个哈希表结构(查找快)
  • HashSet 实现了 Set 接口。

去重原理:

重写了hashCode方法和equals方法,set加入一个对象,首先查看该对象的哈希值,然后看哈希表对应的哈希值是否有对象存储了,如果还没有那么就直接插入哈希表中;如果已经存储着相同哈希值的对象,那么就要使用equals方法比较是不是有相同的对象,如果没有则插入。

注意:哈希表在解决冲突问题的时候采用的是拉链法,在同一个哈希值存储的的元素个数小于8时使用链表,大于等于8就改成了红黑树(红黑树是一棵自平衡的二叉树)

序号方法
1

add(Object o)和addAll(Collection c)增加元素

2

contains(Object o)和containsAll(Collection c)判断元素是否存在

3

isEmpty()判断集合是否为空

4

remove(Object o)和removeAll(Collection c)删除元素

5

size()返回集合的大小

6

clear()清空集合

7

iterator()迭代器

8

toArray()将内容转到数组中

示例:

package test1;

import java.util.HashSet;
import java.util.Iterator;

public class TestHashSet {
    public static void main(String[] args) {
        HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");
        // 重复的元素不会被添加
        System.out.println(sites);
        // 删除元素,删除成功返回 true,否则为 false
        sites.remove("Taobao");
        System.out.println(sites);
        //计算大小
        System.out.println(sites.size());
        //判断是否包含某个元素
        System.out.println(sites.contains("Baidu"));
        //判空
        System.out.println(sites.isEmpty());
        //转换成数组
        for(Object i : sites.toArray()) System.out.println(i);
        //迭代
        Iterator<String> it = sites.iterator();
        while (it.hasNext()) System.out.print(it.next() + "  ");
        System.out.println();
        //清除集合
        sites.clear();
        System.out.println(sites);
    }
}

运行结果:
[Google, Runoob, Zhihu, Taobao]
[Google, Runoob, Zhihu]
3
false
false
Google
Runoob
Zhihu
Google  Runoob  Zhihu  
[]

(二)Map接口

1、HashMap接口

特点:

  • HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
  • HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
  • HashMap 是无序的,即不会记录插入的顺序。
  • HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。
  • HashMap 的 key 与 value 类型可以相同也可以不同,可以是字符串(String)类型的 key 和 value,也可以是整型(Integer)的 key 和字符串(String)类型的 value。

实现的接口:

  • 继承AbstractMap
  • Map 接口
  • Cloneable接口
  • Serializable接口

常用方法:

方法描述
clear()删除 hashMap 中的所有键/值对
clone()复制一份 hashMap
isEmpty()判断 hashMap 是否为空
size()计算 hashMap 中键/值对的数量
put()将键/值对添加到 hashMap 中
putAll()将所有键/值对添加到 hashMap 中
putIfAbsent()如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
remove()删除 hashMap 中指定键 key 的映射关系
containsKey()检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue()检查 hashMap 中是否存在指定的 value 对应的映射关系。
replace()替换 hashMap 中是指定的 key 对应的 value。
replaceAll()将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
get()获取指定 key 对应对 value
getOrDefault()获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach()对 hashMap 中的每个映射执行指定的操作。
entrySet()返回 hashMap 中所有映射项的集合集合视图。
keySet()返回 hashMap 中所有 key 组成的集合视图。
values()返回 hashMap 中存在的所有 value 值。
merge()添加键值对到 hashMap 中
compute()对 hashMap 中指定 key 的值进行重新计算
computeIfAbsent()对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中
computeIfPresent()对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。

示例:

package test1;

import java.util.HashMap;

public class TestHashMap {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites);
        //使用 remove(key) 方法来删除 key 对应的键值对(key-value):
        Sites.remove(4);
        System.out.println(Sites);
        //计算大小
        System.out.println(Sites.size());
        /**
         * 迭代元素
         * 只想获取 key,可以使用 keySet() 方法,然后可以通过 get(key) 获取对应的 value
         * 如果你只想获取 value,可以使用 values() 方法
         * */
        // 输出 key 和 value
        for (Integer i : Sites.keySet()) {
            System.out.println("key: " + i + " value: " + Sites.get(i));
        }
        // 返回所有 value 值
        for(String value: Sites.values()) {
            // 输出每一个value
            System.out.print(value + ", ");
        }
        //删除所有键值对(key-value)可以使用 clear 方法
        Sites.clear();
        System.out.println(Sites);
    }
}

输出结果:
{1=Google, 2=Runoob, 3=Taobao, 4=Zhihu}
{1=Google, 2=Runoob, 3=Taobao}
3
key: 1 value: Google
key: 2 value: Runoob
key: 3 value: Taobao
Google, Runoob, Taobao, {}

2、HashTable接口

概述:

  • Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。
  • Java 2 重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步
  • 像HashMap一样,Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值。然后,该键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。

构造方法:

  • 第一个是默认构造方法:
Hashtable()
  • 第二个构造函数创建指定大小的哈希表:
Hashtable(int size)
  • 第三个构造方法创建了一个指定大小的哈希表,并且通过fillRatio指定填充比例。填充比例必须介于0.0和1.0之间,它决定了哈希表在重新调整大小之前的充满程度:
Hashtable(int size,float fillRatio)
  • 第四个构造方法创建了一个以M中元素为初始化元素的哈希表。哈希表的容量被设置为M的两倍。
Hashtable(Map m)

常用方法:

序号方法描述
1void clear( )
 将此哈希表清空,使其不包含任何键。
2Object clone( )
创建此哈希表的浅表副本。
3boolean contains(Object value)
 测试此映射表中是否存在与指定值关联的键。
4boolean containsKey(Object key)
测试指定对象是否为此哈希表中的键。
5boolean containsValue(Object value)
如果此 Hashtable 将一个或多个键映射到此值,则返回 true。
6Enumeration elements( )
返回此哈希表中的值的枚举。
7Object get(Object key)
 返回指定键所映射到的值,如果此映射不包含此键的映射,则返回 null. 更确切地讲,如果此映射包含满足 (key.equals(k)) 的从键 k 到值 v 的映射,则此方法返回 v;否则,返回 null。
8boolean isEmpty( )
测试此哈希表是否没有键映射到值。
9Enumeration keys( )
 返回此哈希表中的键的枚举。
10Object put(Object key, Object value)
将指定 key 映射到此哈希表中的指定 value。
11void rehash( )
增加此哈希表的容量并在内部对其进行重组,以便更有效地容纳和访问其元素。
12Object remove(Object key)
从哈希表中移除该键及其相应的值。
13int size( )
 返回此哈希表中的键的数量。
14String toString( )
返回此 Hashtable 对象的字符串表示形式,其形式为 ASCII 字符 ", " (逗号加空格)分隔开的、括在括号中的一组条目。

示例:

package test1;

import java.util.Enumeration;
import java.util.Hashtable;

public class TestHashTable {
    public static void main(String args[]) {
        // Create a hash map
        Hashtable balance = new Hashtable();
        Enumeration names;
        String str;
        double bal;

        //将指定 key 映射到此哈希表中的指定 value。
        balance.put("Zara", new Double(3434.34));
        balance.put("Mahnaz", new Double(123.22));
        balance.put("Ayan", new Double(1378.00));
        balance.put("Daisy", new Double(99.22));
        balance.put("Qadir", new Double(-19.08));

        // 返回此哈希表中的键的枚举。
        names = balance.keys();
        while(names.hasMoreElements()) {
            str = (String) names.nextElement();
            System.out.println(str + ": " +
                    balance.get(str));
        }
        System.out.println();
        // 返回指定键所映射到的值
        bal = ((Double)balance.get("Zara")).doubleValue();
        balance.put("Zara", new Double(bal+1000));
        System.out.println("Zara's new balance: " +
                balance.get("Zara"));
    }
}

运行结果:
Qadir: -19.08
Zara: 3434.34
Mahnaz: 123.22
Daisy: 99.22
Ayan: 1378.0

Zara's new balance: 4434.34

3、TreeMap接口

概述:

  • TreeMap存储K-V键值对,通过红黑树(R-B tree)实现;
  • TreeMap继承了NavigableMap接口,NavigableMap接口继承了SortedMap接口,可支持一系列的导航定位以及导航操作的方法,但只是提供了接口,需要TreeMap自己去实现;
  • TreeMap实现了Cloneable接口,可被克隆,实现了Serializable接口,可序列化;
  • TreeMap因为是通过红黑树实现,红黑树结构天然支持排序,默认情况下通过Key值的自然顺序进行排序;

实现接口:

  • Map接口
  • 继承了NavigableMap接口
  • SortedMap接口
  • Cloneable接口
  • Serializable接口

构造方法:

  • TreeMap()创建一个空的TreeMap,并且按照key的自然升序排序;
  • TreeMap(Comparatorcomparator)创建一个空的TreeMap,并且指定排序方法;
  • TreeMap(Mapm)根据给定的Map创建一个TreeMap,按照key的自然升序排序;
  • TreeMap(SortedMapm)根据一个有序的Map创建一个TreeMap,顺序与原Map相同。

常用方法:

序号方法
1public V put(K key,V value)添加一对键值对
2public void putAll(Mapmap)添加一个map的所有键值对
3public V remove(Object key)删除对应的键值对
4public void clear()删除所有元素
5public Map.EntryceilingEntry(K key)返回map中键值不小于参数key的最小键值对应的键值
6public K ceilingKey(K key)返回map中键值不小于参数key的最小键值
7public final boolean containsKey(Object key)判断是否含有某一键值
8public boolean containsValue(Object value)判断是否含有某一value
9public NavigableMapdescendingMap()返回一个降序排列的Map
10public NavigableSetdescendingKeySet()返回一个降序排列的由键名组成的Set
11public Set>entrySet()返回由原Map的键值对组成的Set
12public K firstKey()返回第一个key
13public Map.firstEntry()返回第一个键值对
14public K floorKey(K key)返回Map中不大于指定key的最大key值
15public Map.EntryfloorEntry(K key)返回Map中不大于指定key的最大key值所对应的键值对
16public V get(Object key)取出指定key对应的键值对
17public SortedMapheadMap(K toKey)返回key小于指定key的排序好的Map
18public NavigableMapheadMap(K toKey,boolean inclusive)返回key小于或小于等于指定key
19public K higherKey(K key)返回key严格大于指定key的最小键
20public Map.EntryhigherEntry(K key)返回key严格大于指定key的最小键值对
21public SetkeySet()返回由key组成的Set
22public K lastKey()返回最后一个key
23public Map.EntrylastEntry()返回最后一组键值对
24public K lowerKey(K key)返回key严格小于指定值的最大键
25public Map.EntrylowerEntry(K key)返回key严格小于指定值的最大键值对
26public NavigableMapsubMap(K fromKey,boolean fromInclusive,K toKey,boolean toInclusive)返回key在指定范围内的子Map
27public SortedMapsubMap(K fromKey,K toKey)返回key在指定范围内的子Map
28public NavigableMaptailMap(K fromKey,boolean inclusive)返回key小于或小于等于指定key的排序好的Map
29public SortedMaptailMap(K fromKey)返回key大于指定key的排序好的Map
30public V replace(K key,V value)修改一对键值对
31

public boolean replace(K key,V oldValue,V newValue)如果键值对的原值为指定值,则修改,否则不修改

32public void replaceAll(BiFunctionfunction)按照指定函数运算修改所有键值对
33public Object clone()克隆TreeMap
34public Comparatorcomparator()返回该TreeMap的比较器
35keySet(),entrySet()遍历倒序的descendingKeySet()
36subMap(),tailMap(),headMap()

示例:

package test1;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class TestTreeMap {
    public static void main(String[] args) {
        TreeMap<Integer, String> sites = new TreeMap<Integer, String>();
        // 添加键值对
        sites.put(1, "Google");
        sites.put(2, "Runoob");
        sites.put(3, "Taobao");
        sites.put(4, "Zhihu");
        System.out.println(sites);
        //使用 remove(key) 方法来删除 key 对应的键值对(key-value):
        sites.remove(4);
        System.out.println(sites);
        //计算大小
        System.out.println(sites.size());
        //判断是否含有某一键值
        System.out.println(sites.containsKey(1));
        //判断是否含有某一value
        System.out.println(sites.containsValue("Goodle"));
        //返回一个降序排列的Map
        System.out.println(sites.navigableKeySet());
        //返回第一个key
        System.out.println(sites.firstKey());
        //返回第一个键值对
        System.out.println(sites.firstEntry());
        //修改一对键值对
        sites.replace(1,"Baidu");
        System.out.println(sites);
        //遍历
        //第一种方式
        for(Map.Entry entry : sites.entrySet()) System.out.print(entry + "  ");
        System.out.println();
        //第二种方式
        Iterator iter = sites.entrySet().iterator();
        while (iter.hasNext()) System.out.print(iter.next() + "  ");
        System.out.println();
        //清除
        sites.clear();
    }
}

输出结果:
{1=Google, 2=Runoob, 3=Taobao, 4=Zhihu}
{1=Google, 2=Runoob, 3=Taobao}
3
true
false
[1, 2, 3]
1
1=Google
{1=Baidu, 2=Runoob, 3=Taobao}
1=Baidu  2=Runoob  3=Taobao  
1=Baidu  2=Runoob  3=Taobao  

Process finished with exit code 0

二、Object、泛型与序列化

(一)Object

1、概述

Java Object 类是所有类的父类,位于 java.lang 包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类。

Object 类可以显示继承,也可以隐式继承,以下两种方式时一样:

显示继承:

public class Runoob extends Object{

}

隐式继承:

public class Runoob {

}

2、构造函数

Object() 构造一个新对象。

3、常用方法

序号方法 & 描述
1protected Object clone()

创建并返回一个对象的拷贝

2boolean equals(Object obj)

比较两个对象是否相等

3protected void finalize()

当 GC (垃圾回收器)确定不存在对该对象的有更多引用时,由对象的垃圾回收器调用此方法。

4Class<?> getClass()

获取对象的运行时对象的类

5int hashCode()

获取对象的 hash 值

6void notify()

唤醒在该对象上等待的某个线程

7void notifyAll()

唤醒在该对象上等待的所有线程

8String toString()

返回对象的字符串表示形式

9void wait()

让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。

10void wait(long timeout)

让当前线程处于等待(阻塞)状态,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过参数设置的timeout超时时间。

11void wait(long timeout, int nanos)

与 wait(long timeout) 方法类似,多了一个 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。

(二)泛型

1、概述

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

2、泛型方法

定义泛型方法的规则:

  • 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的 <E>)。
  • 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
  • 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
  • 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char 等)。

java 中泛型标记符:

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  •  - 表示不确定的 java 类型

示例:

public class GenericMethodTest
{
   // 泛型方法 printArray                         
   public static < E > void printArray( E[] inputArray )
   {
      // 输出数组元素            
         for ( E element : inputArray ){        
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }
 
    public static void main( String args[] )
    {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
 
        System.out.println( "整型数组元素为:" );
        printArray( intArray  ); // 传递一个整型数组
 
        System.out.println( "\n双精度型数组元素为:" );
        printArray( doubleArray ); // 传递一个双精度型数组
 
        System.out.println( "\n字符型数组元素为:" );
        printArray( charArray ); // 传递一个字符型数组
    } 
}
运行结果:
整型数组元素为:
1 2 3 4 5 

双精度型数组元素为:
1.1 2.2 3.3 4.4 

字符型数组元素为:
H E L L O 

有界类型的参数:

可能有时候,你会想限制那些被允许传递到一个类型参数的类型种类范围。例如,一个操作数字的方法可能只希望接受Number或者Number子类的实例。这就是有界类型参数的目的。

要声明一个有界的类型参数,首先列出类型参数的名称,后跟extends关键字,最后紧跟它的上界。

public class MaximumTest
{
   // 比较三个值并返回最大值
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假设x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 现在 z 更大           
      }
      return max; // 返回最大对象
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的数为 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
 
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
 
      System.out.printf( "%s, %s 和 %s 中最大的数为 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}
运行结果:
3, 4 和 5 中最大的数为 5

6.6, 8.8 和 7.7 中最大的数为 8.8

pear, apple 和 orange 中最大的数为 pear

3、泛型类

泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。

public class Box<T> {
   
  private T t;
 
  public void add(T t) {
    this.t = t;
  }
 
  public T get() {
    return t;
  }
 
  public static void main(String[] args) {
    //泛型类:Integer类型
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();
 
    integerBox.add(new Integer(10));
    stringBox.add(new String("菜鸟教程"));
 
    System.out.printf("整型值为 :%d\n\n", integerBox.get());
    System.out.printf("字符串为 :%s\n", stringBox.get());
  }
}
运行结果:
整型值为 :10

字符串为 :菜鸟教程

4、类型通配符

(1)类型通配符一般是使用 ? 代替具体的类型参数。例如 List<?> 在逻辑上是 List<String>,List<Integer> 等所有 List<具体类型实参> 的父类。

(2)类型通配符上限通过形如List来定义,如此定义就是通配符泛型值接受Number及其下层子类类型。

(三)序列化

1、序列化条件

  • 该类必须实现 java.io.Serializable 接口。
  • 该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的。

2、序列化作用

  • 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  • 在网络上传送对象的字节序列。

3、序列化与反序列化

  • 序列化:把Java对象转换为字节序列的过程。
  • 反序列化:把字节序列恢复为Java对象的过程。

4、序列化与反序列化步骤

序列化步骤

  • 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
  • 通过对象输出流的writeObject()方法写对象。

反序列化步骤

  • 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
  • 通过对象输入流的readObject()方法读取对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值