Java - 数据结构

欢迎,未来的程序员们!今天,我们将进入Java数据结构的精彩世界。作为你友好邻里的计算机科学老师,我将引导你一步一个脚印地开始这段旅程。如果你是编程新手,不用担心——我们会从基础开始,逐步深入学习。所以,戴上你的虚拟安全帽,让我们一起开始构建知识吧!

Java - Data Structures

数据结构简介

在我们具体探讨Java数据结构之前,让我们先了解什么是数据结构,以及它们为什么如此重要。

想象你正在组织一个图书馆。你不会简单地把所有书堆在一起,对吧?当然不会!你会以某种方式组织它们,以便于查找和管理。这正是数据结构在编程中对我们数据所做的工作。

数据结构是组织和存储数据的方式,以便我们能够高效地访问和修改它。在Java中,我们有几种内置的数据结构可以使用,每一种都有自己的优点和使用场景。

Java内置数据结构

让我们探索一些Java中最常见的数据结构:

枚举(Enumeration)

枚举就像一个依次发放号码的售票机。它是Java中的一个接口,允许我们一次访问集合中的一个元素。

以下是一个简单的例子:

import java.util.*;

public class 枚举示例 {
public static void main(String args[]) {
Vector<String> dayNames = new Vector<>();
dayNames.add("星期一");
dayNames.add("星期二");
dayNames.add("星期三");

Enumeration<String> days = dayNames.elements();

while (days.hasMoreElements()) {
System.out.println(days.nextElement());
}
}
}

在这个例子中,我们创建了一个包含星期名称的Vector,并使用枚举来迭代它们。hasMoreElements()方法检查是否还有更多元素,nextElement()方法检索下一个元素。

位集(BitSet)

位集就像一排灯光开关——每个开关可以是开(1)或关(0)。当需要高效地存储一系列的真/假值时,它非常有用。

以下是一个例子:

import java.util.BitSet;

public class 位集示例 {
public static void main(String args[]) {
BitSet bits1 = new BitSet(16);
BitSet bits2 = new BitSet(16);

// 设置一些位
for(int i = 0; i < 16; i++) {
if((i % 2) == 0) bits1.set(i);
if((i % 5) != 0) bits2.set(i);
}

System.out.println("bits1的初始模式: " + bits1);
System.out.println("bits2的初始模式: " + bits2);

// 执行AND位运算
bits2.and(bits1);
System.out.println("bits2 AND bits1: " + bits2);
}
}

这个例子演示了创建位集、设置位以及执行位运算。

向量(Vector)

向量就像一个可以随意增长或缩小的神奇数组。它与ArrayList相似,但是线程安全的,因为它被同步了。

以下是如何使用向量的一个例子:

import java.util.*;

public class 向量示例 {
public static void main(String args[]) {
Vector<Integer> vec = new Vector<>(3, 2);
System.out.println("初始大小: " + vec.size());
System.out.println("初始容量: " + vec.capacity());

vec.addElement(1);
vec.addElement(2);
vec.addElement(3);
vec.addElement(4);
System.out.println("添加四个元素后的容量: " + vec.capacity());

vec.addElement(5);
System.out.println("当前容量: " + vec.capacity());

System.out.println("第一个元素: " + vec.firstElement());
System.out.println("最后一个元素: " + vec.lastElement());
}
}

这个例子展示了如何创建向量、添加元素以及检查其大小和容量。

栈(Stack)

栈就像一摞盘子——你只能从顶部添加或移除。它遵循后进先出(LIFO)的原则。

让我们看看栈是如何工作的:

import java.util.*;

public class 栈示例 {
public static void main(String args[]) {
Stack<String> stack = new Stack<>();
stack.push("底部");
stack.push("中间");
stack.push("顶部");

System.out.println("栈: " + stack);
System.out.println("弹出: " + stack.pop());
System.out.println("弹出后的栈: " + stack);
System.out.println("窥视: " + stack.peek());
System.out.println("窥视后的栈: " + stack);
}
}

这个例子演示了将元素推入栈、弹出元素以及窥视栈顶元素。

字典(Dictionary)

字典是一个抽象类,代表了一个键值数据结构。它就像一个真实的字典,每个单词(键)都有一个定义(值)。

虽然字典是抽象的,不能直接实例化,但它的子类Hashtable通常被广泛使用:

import java.util.*;

public class 字典示例 {
public static void main(String args[]) {
Dictionary<String, String> dict = new Hashtable<>();

dict.put("苹果", "一种水果");
dict.put("Java", "一种编程语言");
dict.put("计算机", "一种电子设备");

System.out.println("字典: " + dict);
System.out.println("键'Java'的值: " + dict.get("Java"));

System.out.println("键: ");
for (Enumeration<String> keys = dict.keys(); keys.hasMoreElements();) {
System.out.println(keys.nextElement());
}
}
}

这个例子展示了如何使用字典(通过Hashtable)来存储和检索键值对。

散列表(Hashtable)

散列表就像一个超级高效的文件柜。它存储键值对,允许基于键快速检索值。

以下是如何使用散列表的一个例子:

import java.util.*;

public class 散列表示例 {
public static void main(String args[]) {
Hashtable<String, Integer> numbers = new Hashtable<>();
numbers.put("一", 1);
numbers.put("二", 2);
numbers.put("三", 3);

System.out.println("散列表: " + numbers);
System.out.println("键'two'的值: " + numbers.get("二"));
System.out.println("是否存在键'四'? " + numbers.containsKey("四"));
System.out.println("是否包含值3? " + numbers.containsValue(3));

numbers.remove("二");
System.out.println("移除'二'后的散列表: " + numbers);
}
}

这个例子演示了向散列表中添加键值对、检索值、检查键和值以及移除条目。

属性(Properties)

属性是一种特殊的散列表,设计用于存储字符串键值对。它通常用于配置设置。

让我们看看属性是如何工作的:

import java.util.*;

public class 属性示例 {
public static void main(String args[]) {
Properties capitals = new Properties();
capitals.put("USA", "华盛顿D.C.");
capitals.put("France", "巴黎");
capitals.put("Japan", "东京");

System.out.println("属性: " + capitals);
System.out.println("法国的首都: " + capitals.getProperty("France"));

// 设置一个默认值
System.out.println("西班牙的首都: " + capitals.getProperty("Spain", "未找到"));

capitals.list(System.out);
}
}

这个例子展示了如何使用属性来存储和检索字符串键值对,以及为缺失的键设置默认值。

结论

恭喜你!你已经迈出了进入Java数据结构世界的第一步。每一种结构都有自己独特的属性和使用场景。在你继续编程旅程的过程中,你会发现根据具体需求选择不同的结构。

记住,选择正确的数据结构可以大大影响程序运行的效率。这就像选择正确的工具来工作——锤子非常适合敲钉子,但不适合螺丝!

继续练习这些结构,尝试在项目中使用它们,并不要害怕进行实验。快乐编码!

Credits: Image by storyset