Java基础九:集合框架

早在 Java 2 中之前,Java 就提供了特设类。比如:Dictionary, Vector, Stack, 和 Properties 这些类用来存储和操作对象组。虽然这些类都非常有用,但是传统数据结构缺少一个核心的,统一的主题。由于这个原因,使用 Vector 类的方式和使用 Properties 类的方式有着很大不同。

集合框架体系如图所示

图片[1] - Java基础九:集合框架 - 三酷猫笔记

除了集合,该框架也定义了几个 Map 接口和类。Map 里存储的是键/值对。尽管 Map 不是集合,但是它们完全整合在集合中。

了解了集合框架,下面就学习几个常用的集合具体实现类,实际开发中会更有帮助些!

ArrayList

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

import java.util.ArrayList; // 引入 ArrayList 类

ArrayList<E> objectName =new ArrayList<>();  // 初始化 E: 泛型数据类型,只能为引用数据类型。

objectName.add()  // 添加元素
objectName.get()  // 获取元素
objectName.set()   // 修改元素
objectName.remove() // 删除元素,使用下标
objectName.size()   // 获取数组元素个数
Collections.sort(objectName);  // 数组排序
基本类型引用类型
booleanBoolean
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter

LinkedList

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

链表可分为单向链表和双向链表。

一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。

图片[2] - Java基础九:集合框架 - 三酷猫笔记

一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。

图片[3] - Java基础九:集合框架 - 三酷猫笔记

什么时候使用链表?

以下情况使用 ArrayList :

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

以下情况使用 LinkedList :

  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
// 引入 LinkedList 类
import java.util.LinkedList; 

LinkedList<E> list = new LinkedList<E>();   // 普通创建方法
或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表

list.add()  // 添加元素,默认添加接着添加
list.addFirst() // 添加到头部
list.addLast()  // 添加到尾部
list.removeFirst() // 移除头部元素
list.removeLast()  // 移除尾部元素
list.getFirst()    // 获取头部元素
list.get()         // 获取指定位置元素

HashSet

HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。无序,允许有Null值。

import java.util.HashSet; // 引入 HashSet 类
HashSet<String> sites = new HashSet<String>();

sites.add("Runoob");     // 重复的元素不会被添加
sites.remove("Taobao");  // 删除元素,删除成功返回 true,否则为 false
sites.contains("Taobao") // 判断元素是否存在
sites.size()         // 计息大小

HashMap

HashMap 是一个无序散列表,它存储的内容是键值对(key-value)映射。

import java.util.HashMap; // 引入 HashMap 类

HashMap<Integer, String> Sites = new HashMap<Integer, String>();

Sites.put(4, "Zhihu");  // 添加键值对
Sites.get(4);    // 根据键获取对应的值
Sites.remove(4);  // 根据键删除键值对
Sites.keySet();   // 获取HashMap的所有键Set
Sites.values();   // 获取HashMap的所有值

另外一种实例化方式:实例化时赋值

图片[4] - Java基础九:集合框架 - 三酷猫笔记

Iterator(迭代器)

Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法

Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口。

图片[5] - Java基础九:集合框架 - 三酷猫笔记
// 引入 ArrayList 和 Iterator 类
import java.util.ArrayList;
import java.util.Iterator;

public class RunoobTest {
    public static void main(String[] args) {

        // 创建集合
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");

        // 获取迭代器
        Iterator<String> it = sites.iterator();  // 实例化创建一个迭代器

        // 输出集合中的第一个元素
        System.out.println(it.next());
    }
}

Object 类

Java Object 类是所有类的父类,也就是说 Java 的所有类都继承了 Object,子类可以使用 Object 的所有方法

序号方法 & 描述
1 protected 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 纳秒。。
Object类方法介绍

泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

java 中泛型标记符:

  • E – Element (在集合中使用,因为集合中存放的是元素)
  • T – Type(Java 类)
  • K – Key(键)
  • V – Value(值)
  • N – Number(数值类型)
  •  – 表示不确定的 java 类型
 for ( E element : inputArray ){     # 遍历时不指定类型,由系统自动识别是什么类型的,偷懒操作,哈哈   
            System.out.printf( "%s ", element );
         }
System.out.println();

序列化

Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型

将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。

类对象序列化的要求,必须满足两个条件:

该类必须实现 java.io.Serializable 接口。

该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的。

public class Employee implements java.io.Serializable
{
   public String name;
   public String address;
   public transient int SSN;
   public int number;
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + name
                           + " " + address);
   }
}

序列化对象

注意: 当序列化一个对象到文件时, 按照 Java 的标准约定是给文件一个 .ser 扩展名。

import java.io.*;
 
public class SerializeDemo
{
   public static void main(String [] args)
   {
      Employee e = new Employee();
      e.name = "Reyan Ali";
      e.address = "Phokka Kuan, Ambehta Peer";
      e.SSN = 11122333;
      e.number = 101;
      try
      {
         FileOutputStream fileOut =
         new FileOutputStream("/tmp/employee.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
         out.writeObject(e);
         out.close();
         fileOut.close();
         System.out.printf("Serialized data is saved in /tmp/employee.ser");
      }catch(IOException i)
      {
          i.printStackTrace();
      }
   }
}

反序列化对象

下面的 DeserializeDemo 程序实例了反序列化,/tmp/employee.ser 存储了 Employee 对象。

import java.io.*;
 
public class DeserializeDemo
{
   public static void main(String [] args)
   {
      Employee e = null;
      try
      {
         FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         e = (Employee) in.readObject();
         in.close();
         fileIn.close();
      }catch(IOException i)
      {
         i.printStackTrace();
         return;
      }catch(ClassNotFoundException c)
      {
         System.out.println("Employee class not found");
         c.printStackTrace();
         return;
      }
      System.out.println("Deserialized Employee...");
      System.out.println("Name: " + e.name);
      System.out.println("Address: " + e.address);
      System.out.println("SSN: " + e.SSN);
      System.out.println("Number: " + e.number);
    }
}

以上程序编译运行结果如下所示:

图片[6] - Java基础九:集合框架 - 三酷猫笔记
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享