目录
01、Java一维数组概念与应用
(1)定义与基本使用
一维数组的定义:一维数组是一种线性数据结构,它包含固定数量的元素,这些元素具有相同的类型和名称。一维数组中的元素按照顺序排列,可以通过索引访问。
一维数组的定义:一维数组是一种线性数据结构,它包含固定数量的元素,这些元素具有相同的类型和名称。一维数组中的元素按照顺序排列,可以通过索引访问。
(2)实例
下段代码创建了一个长度为5的整数数组,并将其初始化为包含一些值的数组。然后使用循环打印数组的每个元素
public class Main {
public static void main(String[] args) {
// 创建一个长度为5的整数数组
int[] array = new int[5];
// 初始化数组
array[0] = 10;
array[1] = 20;
array[2] = 30;
array[3] = 40;
array[4] = 50;
// 打印数组元素
for (int i = 0; i < array.length; i++) {
System.out.println("Element at index " + i + ": " + array[i]);
}
}
}
一维数组求最大值
通过遍历一维数组,将每个元素与当前最大值进行比较,得出数组中的最大值。
代码:
在这个示例中,我们首先初始化 maxValue
为数组的第一个元素。然后,我们遍历数组,如果找到比 maxValue
更大的元素,就更新 maxValue
。最后,我们打印出数组中的最大值。
public class Main {
public static void main(String[] args) {
// 创建一个一维数组
int[] array = {10, 20, 30, 40, 50};
// 初始化最大值为数组的第一个元素
int maxValue = array[0];
// 遍历数组,查找最大值
for (int i = 1; i < array.length; i++) {
if (array[i] > maxValue) {
maxValue = array[i];
}
}
// 打印最大值
System.out.println("数组中的最大值是: " + maxValue);
}
}
一维数组求最小值
通过遍历一维数组,将每个元素与当前最小值进行比较,得出数组中的最小值。
代码:
在这个示例中,我们首先将 minValue
初始化为数组的第一个元素。然后,我们遍历数组,如果找到比 minValue
更小的元素,就更新 minValue
。最后,我们打印出数组中的最小值。
public class Main {
public static void main(String[] args) {
// 创建一个一维数组
int[] array = {10, 20, 30, 40, 50};
// 初始化最小值为数组的第一个元素
int minValue = array[0];
// 遍历数组,查找最小值
for (int i = 1; i < array.length; i++) {
if (array[i] < minValue) {
minValue = array[i];
}
}
// 打印最小值
System.out.println("数组中的最小值是: " + minValue);
}
}
02、Java二维数组概念与应用
定义与基本使用
二维数组的定义:二维数组是一种多维数据结构,由多个一维数组组成。每个一维数组称为该二维数组的行或子数组,行数和列数可以不同。
二维数组的结构特点:二维数组由多个一维数组组成,每个一维数组代表一行数据,具有相同的列数,可以灵活地存储和操作多行多列的数据。
二维数组的应用:二维数组广泛应用于图像处理、数据分析、游戏开发等领域,通过遍历和操作二维数组中的元素,实现各种功能和算法。
代码
下段代码创建了一个 3x3 的二维整数数组 matrix
,并初始化了其元素。然后使用嵌套的循环遍历并打印二维数组的每个元素。
public class Main {
public static void main(String[] args) {
// 创建一个 3x3 的二维整数数组
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 打印二维数组
System.out.println("二维数组的内容:");
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // 换行
}
}
}
二维数组查找最大值
通过对二维数组进行逐行逐列的遍历,找出所有元素中的最大值,以实现对二维数组中最大值的查找。
代码:
在这个示例中,我们首先将 maxValue
初始化为数组的第一个元素。然后,我们使用嵌套的循环遍历整个二维数组,比较每个元素并更新 maxValue
。最后,我们打印出二维数组中的最大值。
public class Main {
public static void main(String[] args) {
// 创建一个二维数组
int[][] array = {
{10, 20, 30},
{40, 50, 60},
{70, 80, 90}
};
// 初始化最大值为数组的第一个元素
int maxValue = array[0][0];
// 遍历二维数组,查找最大值
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] > maxValue) {
maxValue = array[i][j];
}
}
}
// 打印最大值
System.out.println("二维数组中的最大值是: " + maxValue);
}
}
03、Java集合框架简介
List, Set, Map接口概述
Java集合框架简介:Java集合框架是Java提供的一种用于存储和操作数据的数据结构,包括List、Set、Map等接口及其实现类。
List接口概述:List接口是一种有序的集合,可以包含重复的元素,常用的实现类有ArrayList和LinkedList。
Set接口概述:Set接口是一种无序的集合,不允许包含重复的元素,常用的实现类有HashSet和TreeSet。
ArrayList的动态扩容特性:当ArrayList中的元素数量超过其当前的容量时,它会自动进行扩容,以容纳更多的元素,这是ArrayList动态数组的核心特性之一。
ArrayList的自动装箱和拆箱功能:ArrayList提供了高效的随机访问方法,如get和set,使得元素的查找和修改变得非常快速,这也是它作为动态数组的重要优势之一。
04、ArrayList集合详解
(1)动态扩容机制
动态扩容机制的概念:动态扩容机制是ArrayList集合在元素添加过程中,当当前容量不足以容纳新元素时,自动调整其容量的策略。
动态扩容机制的实现方式:动态扩容机制通过创建一个新的、更大的数组,并将原数组的元素复制到新数组中,从而实现容量的扩展。
动态扩容机制的影响:动态扩容机制可以提高ArrayList集合的性能,因为它减少了数组拷贝的次数,但同时也可能带来一定的性能开销,因为每次扩容都需要创建新的数组并复制元素。
(2)实例
一个简单的ArrayList代码运用。
在这个示例中,我们首先导入了 ArrayList 类。然后,我们创建了一个名为 arrayList
的 ArrayList,并向其中添加了几个字符串元素。最后,我们使用 for 循环访问 ArrayList 中的元素,并将它们打印出来。
import java.util.ArrayList; // 导入 ArrayList 类
public class Main {
public static void main(String[] args) {
// 创建一个 ArrayList
ArrayList<String> arrayList = new ArrayList<>();
// 向 ArrayList 中添加元素
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add("Orange");
// 访问 ArrayList 中的元素
System.out.println("ArrayList 中的元素:");
for (String element : arrayList) {
System.out.println(element);
}
}
}
ArrayList添加元素
ArrayList提供了add()方法,可以向列表的末尾添加一个元素,也可以在指定位置插入元素。
解释代码:
-
导入包:导入
java.util.ArrayList
包,以便可以使用ArrayList
类。 -
创建ArrayList:使用
ArrayList<Integer>
创建一个名为numbers
的ArrayList
对象,该对象存储整数类型的元素。 -
添加元素:
- 使用
add()
方法向numbers
中依次添加整数元素 10、20 和 30。 - 使用
add(index, element)
方法在索引为 1 的位置插入整数元素 15。
- 使用
-
遍历并打印元素:使用
for
循环遍历ArrayList
,并使用get(i)
方法获取每个索引处的元素,并打印出来
import java.util.ArrayList; // 导入ArrayList类
public class ArrayListExample {
public static void main(String[] args) {
// 创建一个ArrayList对象,存储整数类型的元素
ArrayList<Integer> numbers = new ArrayList<>();
// 添加元素到ArrayList中
numbers.add(10);
numbers.add(20);
numbers.add(30);
// 添加元素到特定位置
numbers.add(1, 15); // 在索引为1的位置插入元素15
// 遍历ArrayList并打印元素
System.out.println("ArrayList中的元素:");
for (int i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
}
}
这段代码演示了如何创建 ArrayList
,向其中添加元素,并遍历打印出所有元素。
ArrayList删除元素
ArrayList提供了remove()和remove(int index)方法,可以删除列表中的元素或指定位置的元素。
解释代码:
-
导入包:导入
java.util.ArrayList
包,以便可以使用ArrayList
类。 -
创建ArrayList:使用
ArrayList<String>
创建一个名为colors
的ArrayList
对象,该对象存储字符串类型的元素。 -
添加元素:
- 使用
add()
方法向colors
中依次添加字符串元素 "Red"、"Green"、"Blue"、"Yellow" 和 "Orange"。
- 使用
-
打印原始ArrayList中的元素:使用
System.out.println()
打印出原始ArrayList
中的所有元素。 -
删除元素:
- 使用
remove(index)
方法删除索引为 2 的元素,即删除 "Blue"。 - 使用
remove(object)
方法删除值为 "Green" 的元素,并将删除结果存储在removed
变量中。
- 使用
-
打印删除后的ArrayList中的元素:使用
System.out.println()
打印出删除元素后的ArrayList
中的所有元素。 -
打印删除成功与否:根据
removed
的布尔值判断是否成功删除 "Green",并相应打印结果。
import java.util.ArrayList; // 导入ArrayList类
public class ArrayListRemoveExample {
public static void main(String[] args) {
// 创建一个ArrayList对象,存储字符串类型的元素
ArrayList<String> colors = new ArrayList<>();
// 添加元素到ArrayList中
colors.add("Red");
colors.add("Green");
colors.add("Blue");
colors.add("Yellow");
colors.add("Orange");
// 打印原始ArrayList中的元素
System.out.println("原始ArrayList中的元素:");
System.out.println(colors);
// 删除指定索引处的元素
colors.remove(2); // 删除索引为2的元素,即"Blue"
// 删除指定元素
boolean removed = colors.remove("Green"); // 删除值为"Green"的元素
// 打印删除后的ArrayList中的元素
System.out.println("删除后的ArrayList中的元素:");
System.out.println(colors);
// 打印是否成功删除"Green"
if (removed) {
System.out.println("成功删除元素\"Green\"");
} else {
System.out.println("未找到元素\"Green\",无法删除");
}
}
}
这段代码演示了如何使用 remove()
方法从 ArrayList
中删除元素。
ArrayList元素的遍历
可以使用for-each循环或者迭代器来遍历ArrayList中的每一个元素。
解释代码:
-
导入包:导入
java.util.ArrayList
包,以便可以使用ArrayList
类。 -
创建ArrayList:使用
ArrayList<Integer>
创建一个名为numbers
的ArrayList
对象,该对象存储整数类型的元素。 -
添加元素:
- 使用
add()
方法向numbers
中依次添加整数元素 10、20、30、40 和 50。
- 使用
-
for-each 循环遍历:
- 使用
for (Integer number : numbers)
语法,遍历numbers
中的每个元素,每次迭代将当前元素赋值给number
变量。 - 在循环体内使用
System.out.println(number)
打印每个元素的值。
- 使用
import java.util.ArrayList; // 导入ArrayList类
public class ArrayListForEachExample {
public static void main(String[] args) {
// 创建一个ArrayList对象,存储整数类型的元素
ArrayList<Integer> numbers = new ArrayList<>();
// 添加元素到ArrayList中
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
numbers.add(50);
// 使用for-each循环遍历ArrayList中的元素
System.out.println("使用for-each循环遍历ArrayList中的元素:");
for (Integer number : numbers) {
System.out.println(number);
}
}
}
这段代码演示了如何使用 for-each 循环遍历 ArrayList
中的元素,并逐个打印出来。这种遍历方式简洁明了,适合对集合中的每个元素执行相同操作的场景。
总结
ArrayList
是 Java 中的一个常用集合类,它实现了 List
接口,提供了一种动态数组的实现方式。下面是对 ArrayList
的总结:
-
特点:
ArrayList
是基于数组实现的,可以动态调整大小。- 允许存储重复元素。
- 允许存储
null
元素。 - 提供了快速随机访问元素的能力。
-
优点:
- 动态大小:
ArrayList
的大小可以动态增长或缩小,根据需要自动调整内部数组的大小。 - 简单易用:
ArrayList
提供了大量方便的方法来操作集合元素,如添加、删除、遍历等。 - 高效的随机访问:由于
ArrayList
基于数组实现,可以通过索引快速访问和修改元素。
- 动态大小:
-
缺点:
- 删除元素时可能需要移动其他元素:当从
ArrayList
中删除一个元素时,后续的元素会向前移动,导致性能下降。 - 频繁插入/删除元素时效率低:由于需要移动元素,频繁执行插入和删除操作会导致性能下降。
- 不适合大量数据的场景:由于
ArrayList
的内部实现是数组,如果需要处理大量的数据,可能会占用大量的内存空间。
- 删除元素时可能需要移动其他元素:当从
-
常用操作:
- 添加元素:使用
add()
方法将元素添加到ArrayList
的末尾。 - 获取元素:使用索引访问
ArrayList
中的元素,如get(index)
。 - 更新元素:使用索引和
set(index, element)
方法更新ArrayList
中的元素。 - 删除元素:使用索引或元素对象删除
ArrayList
中的元素,如remove(index)
或remove(element)
。 - 遍历元素:使用 for-each 循环或迭代器遍历
ArrayList
中的元素。
- 添加元素:使用
ArrayList
是 Java 集合框架中非常常用的集合类之一,具有动态调整大小、简单易用和高效的随机访问等特点。在很多场景下,它是处理集合数据的首选。然而,如果需要频繁执行插入和删除操作,或者处理大量数据,可能需要考虑其他集合类的选择。
05、HashMap集合详解
散列存储原理
散列函数的工作原理:散列函数是把任意长度的消息压缩到某一固定长度的消息摘要的函数,其输出结果就是哈希值。
碰撞与解决策略:由于散列函数的输出空间有限,两个不同的输入可能会产生相同的哈希值,这种现象称为碰撞。解决策略包括链地址法和开放地址法。
HashMap的存储结构:HashMap是基于哈希表实现的一种键值对集合,它通过将键映射到哈希表中的位置,快速地插入、删除和查找元素。
键值对映射存储特点
映射关系明确:HashMap集合中,键值对的映射关系非常明确,通过键就可以直接找到对应的值,这种特性使得数据的查找和操作变得高效。
存储容量可变:HashMap集合的存储容量是可变的,它会随着数据的增加而自动扩容,避免了因容量不足而导致的性能问题。
数据唯一性:HashMap集合中的键是唯一的,即同一个键只能对应一个值,这种特性保证了数据的唯一性,避免了重复数据的存储。
线程不安全与解决策略
HashMap线程不安全的原因:HashMap在多线程环境下,因为其内部的hash表数组的扩容、rehash等操作不是原子性的,所以会出现线程安全问题。
线程安全的HashTable替代方案:当需要使用线程安全的HashMap时,Java提供了ConcurrentHashMap作为HashTable的线程安全替代方案,它采用了分段锁技术,实现了高效的并发访问。
解决策略:使用Collections.synchronizedMap:另一种解决线程不安全问题的策略是使用Collections.synchronizedMap方法将普通的HashMap转换为线程安全的Map,这样在多线程环境下可以保证对Map的操作是原子性的。
特点和优点
-
键值对存储:
HashMap
以键值对 (key-value) 形式存储数据,其中每个键(Key)是唯一的,但值(Value)可以重复。
-
高效的查找和操作:
- 基于哈希表实现,
HashMap
提供了 O(1) 复杂度的快速查找、插入和删除操作,在平均情况下效率非常高。
- 基于哈希表实现,
-
允许
null
键和值:HashMap
允许一个null
键和多个null
值。
-
无序:
HashMap
不保证元素的顺序,元素的顺序取决于哈希函数和散列桶的状态。
-
线程不安全:
HashMap
是非同步的,不是线程安全的。如果在多线程环境中使用,可以考虑使用Collections.synchronizedMap()
方法将其同步化,或者使用ConcurrentHashMap
。
常用操作
1.创建 HashMap
:
HashMap<KeyType, ValueType> map = new HashMap<>();
2.添加键值对:
map.put(key, value);
3.获取值:
ValueType value = map.get(key);
4.删除键值对:
map.remove(key);
5.检查是否包含键或值:
boolean containsKey = map.containsKey(key);
boolean containsValue = map.containsValue(value);
6.获取大小:
int size = map.size();
7.遍历 HashMap
:
使用 entrySet
遍历键值对:
for (Map.Entry<KeyType, ValueType> entry : map.entrySet()) {
KeyType key = entry.getKey();
ValueType value = entry.getValue();
}
使用 keySet
遍历键:
for (KeyType key : map.keySet()) {
ValueType value = map.get(key);
}
8.清空 HashMap
:
map.clear();
示例代码
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
// 创建一个HashMap
HashMap<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("Apple", 10);
map.put("Banana", 20);
map.put("Orange", 30);
// 获取并打印值
System.out.println("Apple: " + map.get("Apple"));
// 删除键值对
map.remove("Banana");
// 检查是否包含键或值
System.out.println("Contains 'Orange': " + map.containsKey("Orange"));
System.out.println("Contains value 20: " + map.containsValue(20));
// 遍历HashMap
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 获取大小
System.out.println("Size of the map: " + map.size());
// 清空HashMap
map.clear();
System.out.println("Is map empty? " + map.isEmpty());
}
}
总结
HashMap
是一种高效的键值对存储结构,适用于频繁查找、插入和删除操作的场景。- 由于其非同步性,在多线程环境中使用时需要额外注意线程安全问题。
- 允许
null
键和值,使其在处理某些特殊情况时更加灵活。 - 由于无序性,如果需要保持插入顺序或其他顺序要求,可以考虑使用
LinkedHashMap
或TreeMap
。