javaj进阶(中)

news/2025/2/12 12:22:46/文章来源:https://www.cnblogs.com/bbdhl/p/18706220

java进阶(中)

集合

  • 集合的特点

    1. 可以动态保存任意多个对象,使用比较方便
    2. 提供了一系列方便的操作对象的方法:add、remove、set、get
  • java集合类很多,主要分为两大类,如图

LInk(接口)

ArrayList(Link实现类)

  • ArrayList 是 Java 中最常用的集合类之一,它实现了 List 接口,基于动态数组实现,允许动态地添加和删除元素。以下是 ArrayList 的常用方法及其使用示例:
1. 构造方法

ArrayList 提供了多种构造方法,用于创建不同类型的实例:

  • 无参构造方法:创建一个空的 ArrayList,默认初始容量为10。

    ArrayList<String> list1 = new ArrayList<>();
    
  • 指定初始容量的构造方法:创建一个具有指定初始容量的空 ArrayList

    ArrayList<String> list2 = new ArrayList<>(100);
    
  • 从其他集合构造:创建一个包含指定集合元素的 ArrayList

    ArrayList<String> list3 = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));
    
2. 添加元素

ArrayList 提供了多种方法用于添加元素:

  • add(E e):在列表末尾添加一个元素。

    list1.add("Apple");
    list1.add("Banana");
    
  • add(int index, E e):在指定位置插入一个元素。

    list1.add(1, "Orange"); // 在索引1的位置插入"Orange"
    
3. 删除元素

ArrayList 提供了多种方法用于删除元素:

  • remove(int index):删除指定索引位置的元素,并返回被删除的元素。

    String removedElement = list1.remove(1); // 删除索引为1的元素
    System.out.println("Removed element: " + removedElement);
    
  • remove(Object o):删除第一个匹配的元素。

    list1.remove("Banana"); // 删除第一个"Banana"
    
4. 访问元素

ArrayList 提供了多种方法用于访问元素:

  • get(int index):获取指定索引位置的元素。

    String element = list1.get(0); // 获取索引为0的元素
    System.out.println("Element at index 0: " + element);
    
  • indexOf(Object o):返回指定元素第一次出现的索引,如果不存在则返回-1。

    int index = list1.indexOf("Apple");
    System.out.println("Index of 'Apple': " + index);
    
  • lastIndexOf(Object o):返回指定元素最后一次出现的索引,如果不存在则返回-1。

    int lastIndex = list1.lastIndexOf("Apple");
    System.out.println("Last index of 'Apple': " + lastIndex);
    
5. 更新元素

ArrayList 提供了方法用于更新指定位置的元素:

  • set(int index, E e):替换指定索引位置的元素,并返回被替换的元素。

    String oldElement = list1.set(0, "Grape"); // 将索引为0的元素替换为"Grape"
    System.out.println("Old element: " + oldElement);
    
6. 遍历元素

ArrayList 可以通过多种方式遍历:

  • for-each 循环

    for (String fruit : list1) {System.out.println(fruit);
    }
    
  • for 循环

    for (int i = 0; i < list1.size(); i++) {System.out.println(list1.get(i));
    }
    
  • Iterator

    Iterator<String> iterator = list1.iterator();
    while (iterator.hasNext()) {System.out.println(iterator.next());
    }
    
  • Stream API(Java 8及以上):

    list1.stream().forEach(System.out::println);
    
7. 其他常用方法
  • size():返回列表中的元素数量。

    int size = list1.size();
    System.out.println("Size of list: " + size);
    
  • isEmpty():判断列表是否为空。

    boolean isEmpty = list1.isEmpty();
    System.out.println("Is list empty? " + isEmpty);
    
  • clear():清空列表中的所有元素。

    list1.clear();
    System.out.println("List after clearing: " + list1);
    
  • contains(Object o):判断列表是否包含指定元素。

    boolean contains = list1.contains("Apple");
    System.out.println("Does list contain 'Apple'? " + contains);
    
  • toArray():将列表转换为数组。

    Object[] array = list1.toArray();
    System.out.println("Array: " + Arrays.toString(array));
    
  • subList(int fromIndex, int toIndex):返回列表的一个子列表,范围为fromIndextoIndex-1

    List<String> sublist = list1.subList(1, 3);
    System.out.println("Sublist: " + sublist);
    

LinkedList (Link实现类)

LinkedList 是 Java 中的一个非常重要的集合类,它实现了 List 接口和 Deque 接口(双端队列)。LinkedList 基于双向链表实现,具有以下特点和用途:

1. 特点
  • 基于双向链表:每个元素都包含一个指向下一个元素的引用和一个指向前一个元素的引用。这种结构使得插入和删除操作非常高效,时间复杂度为 O(1)。
  • 动态大小LinkedList 的大小是动态的,可以根据需要自动扩展。
  • 支持多种操作:除了 List 接口提供的方法外,LinkedList 还提供了额外的方法来支持队列和双端队列的操作。
2. 常用方法

以下是 LinkedList 的一些常用方法,按功能分类:

2.1 添加元素
  • add(E e):将元素添加到链表的末尾。

    LinkedList<String> list = new LinkedList<>();
    list.add("Apple");
    list.add("Banana");
    
  • addFirst(E e):将元素添加到链表的头部。

    list.addFirst("Orange");
    
  • addLast(E e):将元素添加到链表的尾部(等同于add(E e))。

    list.addLast("Cherry");
    
  • add(int index, E e):在指定位置插入元素。

    list.add(1, "Grape");
    
2.2 删除元素
  • remove():删除链表头部的元素,并返回被删除的元素。

    String removed = list.remove();
    
  • removeLast():删除链表尾部的元素,并返回被删除的元素。

    String removedLast = list.removeLast();
    
  • remove(Object o):删除第一个匹配的元素。

    list.remove("Banana");
    
  • remove(int index):删除指定索引位置的元素,并返回被删除的元素。

    String removedAtIndex = list.remove(1);
    
2.3 访问元素
  • get(int index):获取指定索引位置的元素。

    String element = list.get(1);
    
  • getFirst():获取链表头部的元素,但不删除。

    String first = list.getFirst();
    
  • getLast():获取链表尾部的元素,但不删除。

    String last = list.getLast();
    
2.4 队列操作
  • poll():获取并删除链表头部的元素。如果链表为空,则返回null

    String polled = list.poll();
    
  • pollLast():获取并删除链表尾部的元素。如果链表为空,则返回null

    String polledLast = list.pollLast();
    
  • offer(E e):将元素添加到链表尾部,等同于add(E e)

    list.offer("Mango");
    
  • offerFirst(E e):将元素添加到链表头部。

    list.offerFirst("Kiwi");
    
  • offerLast(E e):将元素添加到链表尾部(等同于offer(E e))。

    list.offerLast("Peach");
    
2.5 其他方法
  • size():返回链表中的元素数量。

    int size = list.size();
    
  • isEmpty():判断链表是否为空。

    boolean isEmpty = list.isEmpty();
    
  • clear():清空链表中的所有元素。

    list.clear();
    
  • contains(Object o):判断链表是否包含指定元素。

    boolean contains = list.contains("Apple");
    
3. 遍历 LinkedList

LinkedList 可以通过多种方式遍历:

3.1 使用 for-each 循环
for (String fruit : list) {System.out.println(fruit);
}
3.2 使用 Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {System.out.println(iterator.next());
}
3.3 使用 ListIterator

ListIterator 支持双向遍历,并且可以在遍历过程中插入、删除和替换元素。

ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {System.out.println(listIterator.next());
}
3.4 使用 Stream API(Java 8及以上)
list.stream().forEach(System.out::println);
4. 使用场景
  • 频繁插入和删除LinkedList 的插入和删除操作非常高效,适用于需要频繁进行这些操作的场景。
  • 队列和双端队列LinkedList 实现了 Deque 接口,支持队列和双端队列的所有操作,非常适合用作队列或双端队列。
  • 需要双向遍历LinkedList 支持双向遍历,可以通过 ListIterator 实现向前和向后遍历。

Set (接口)

  • Set接口简介
    1. 无序,没有索引
    2. 不允许重复元素,所以最多包含一个null

HashSet (Set实现类)

  • HashSet 是 Java 中一个非常重要的集合类,它实现了 Set 接口,基于哈希表(HashMap)实现。HashSet 不允许重复元素,并且不保证元素的顺序。以下是关于 HashSet 的详细介绍,包括其特点、常用方法和使用示例。
1. 特点
  • 不允许重复元素HashSet 中的元素必须是唯一的,重复的元素不会被添加。
  • 无序性HashSet 不保证元素的顺序,元素的存储顺序可能与添加顺序不同。
  • 基于哈希表实现:底层使用 HashMap 来存储元素,通过哈希函数将元素映射到哈希表中。
  • 线程不安全HashSet 是线程不安全的,如果需要在多线程环境中使用,可以使用 Collections.synchronizedSet 包装,或者使用线程安全的集合类(如 ConcurrentHashMap 包装的 Set)。
2. 常用方法

以下是 HashSet 的一些常用方法:

2.1 添加元素
  • add(E e):向集合中添加一个元素。如果元素已存在,则不会添加,并返回 false

    HashSet<String> set = new HashSet<>();
    set.add("Apple");
    set.add("Banana");
    set.add("Cherry");
    
2.2 删除元素
  • remove(Object o):从集合中删除指定的元素。如果元素存在,则删除并返回 true;否则返回 false

    set.remove("Banana");
    
2.3 检查元素
  • contains(Object o):检查集合中是否包含指定的元素。如果存在,则返回 true;否则返回 false

    boolean containsApple = set.contains("Apple");
    
  • isEmpty():检查集合是否为空。如果集合为空,则返回 true;否则返回 false

    boolean isEmpty = set.isEmpty();
    
2.4 获取集合大小
  • size():返回集合中的元素数量。

    int size = set.size();
    
2.5 清空集合
  • clear():清空集合中的所有元素。

    set.clear();
    
2.6 遍历集合

HashSet 可以通过多种方式遍历:

  • for-each 循环

    for (String fruit : set) {System.out.println(fruit);
    }
    
  • Iterator

    Iterator<String> iterator = set.iterator();
    while (iterator.hasNext()) {System.out.println(iterator.next());
    }
    
  • Stream API(Java 8及以上)

    set.stream().forEach(System.out::println);
    
3. 使用场景
  • 去重HashSet 最常见的用途是去除重复元素。
  • 快速查找:由于基于哈希表实现,HashSet 提供了快速的查找性能(平均时间复杂度为 O(1))。
  • 集合操作:可以方便地进行集合操作,如并集、交集、差集等。

Map(接口)

Java 中的 Map 接口 是一个非常重要的数据结构,用来存储键值对(Key-Value Pair)。下面我会用简单易懂的方式介绍它:

1. 什么是 Map 接口?

Map 是一个接口,它定义了一种数据结构,用来存储键(Key)和值(Value)的映射关系。每个键都对应一个值,就像一个字典,通过键来查找对应的值。

  • 键(Key):必须是唯一的,不能重复。如果添加了重复的键,原来的键对应的值会被覆盖。
  • 值(Value):可以重复,同一个值可以对应多个键。

2. 常见的 Map 实现类

Java 提供了几种常用的 Map 实现类,每种都有不同的特点:

  • HashMap
    • 特点:基于哈希表实现,查找速度快,但不保证键值对的顺序。
    • 用途:适合需要快速查找的场景,比如存储用户信息(用户名作为键,用户详情作为值)。
  • TreeMap
    • 特点:基于红黑树实现,按键的自然顺序或指定的比较器排序。
    • 用途:适合需要按键排序的场景,比如统计成绩并按分数排序。
  • LinkedHashMap
    • 特点:基于哈希表和双向链表实现,保持插入顺序或访问顺序。
    • 用途:适合需要保持插入顺序的场景,比如最近访问的网页记录。

HashMap类(map接口实现类)

HashMap是Java集合框架中的一个类,用于存储键值对(key-value pairs)。它基于哈希表实现,允许快速插入、删除和查找操作。HashMap允许一个null键和多个null值。

HashMap的主要特点

  1. 无序HashMap不保证键值对的顺序。
  2. 允许null值和null键:可以有一个null键和多个null值。
  3. 非同步HashMap不是线程安全的。如果需要线程安全的操作,可以使用Collections.synchronizedMap方法来包装HashMap,或者使用ConcurrentHashMap
  4. 快速访问:通过哈希表实现,提供了快速的插入、删除和查找操作。

常用方法

  • put(K key, V value):将指定的值与该键关联。如果该键已存在,则更新其值。
  • get(Object key):返回指定键所映射的值,如果此映射不包含该键的映射关系,则返回null
  • remove(Object key):如果存在键的映射关系,则将其从映射中移除。
  • containsKey(Object key):如果此映射包含指定键的映射关系,则返回true
  • containsValue(Object value):如果此映射将一个或多个键映射到指定值,则返回true
  • size():返回此映射中的键值对数量。
  • isEmpty():如果此映射不包含键值对,则返回true
  • clear():从此映射中移除所有键值对。

示例代码

下面是一个简单的HashMap示例:

java复制

import java.util.HashMap;public class HashMapExample {public static void main(String[] args) {// 创建一个HashMap实例HashMap<String, Integer> map = new HashMap<>();// 添加键值对到HashMapmap.put("Apple", 10);map.put("Banana", 20);map.put("Orange", 30);map.put("Mango", 40);// 获取并打印值System.out.println("Value for key 'Apple': " + map.get("Apple"));// 检查是否包含某个键System.out.println("Contains key 'Banana': " + map.containsKey("Banana"));// 检查是否包含某个值System.out.println("Contains value 30: " + map.containsValue(30));// 移除键值对map.remove("Orange");// 遍历HashMapfor (String key : map.keySet()) {System.out.println("Key: " + key + ", Value: " + map.get(key));}// 打印HashMap的大小System.out.println("Size of the map: " + map.size());// 清空HashMapmap.clear();System.out.println("Is map empty? " + map.isEmpty());}
}

IO流

  • 在Java中,IO(输入/输出)流是用于处理数据输入和输出的机制。Java提供了丰富的IO流类库,这些类库位于java.io包中。IO流可以分为两大类:字节流和字符流。字节流用于处理二进制数据,字符流用于处理文本数据。

以下是一些常见的IO流类及其用途:

字节流

  • InputStream:抽象类,所有字节输入流的父类。
  • OutputStream:抽象类,所有字节输出流的父类。
  • FileInputStream:用于从文件中读取字节数据。
  • FileOutputStream:用于向文件写入字节数据。
  • BufferedInputStream:带有缓冲区的输入流,可以提高读取效率。
  • BufferedOutputStream:带有缓冲区的输出流,可以提高写入效率。

字符流

  • Reader:抽象类,所有字符输入流的父类。
  • Writer:抽象类,所有字符输出流的父类。
  • FileReader:用于从文件中读取字符数据。
  • FileWriter:用于向文件写入字符数据。
  • BufferedReader:带有缓冲区的字符输入流,可以提高读取效率。
  • BufferedWriter:带有缓冲区的字符输出流,可以提高写入效率。

示例代码

以下是一些使用Java IO流的示例代码,展示如何读取和写入文件。

示例1:使用字节流读取和写入文件

java复制

import java.io.*;public class ByteStreamExample {public static void main(String[] args) {String inputFilePath = "input.txt";String outputFilePath = "output.txt";// 使用FileInputStream读取文件try (FileInputStream fis = new FileInputStream(inputFilePath);BufferedInputStream bis = new BufferedInputStream(fis)) {// 使用FileOutputStream写入文件try (FileOutputStream fos = new FileOutputStream(outputFilePath);BufferedOutputStream bos = new BufferedOutputStream(fos)) {int byteRead;while ((byteRead = bis.read()) != -1) {bos.write(byteRead);}System.out.println("File copied successfully!");} catch (IOException e) {System.err.println("Error writing to file: " + e.getMessage());}} catch (IOException e) {System.err.println("Error reading from file: " + e.getMessage());}}
}

示例2:使用字符流读取和写入文件

java复制

import java.io.*;public class CharStreamExample {public static void main(String[] args) {String inputFilePath = "input.txt";String outputFilePath = "output.txt";// 使用FileReader读取文件try (FileReader fr = new FileReader(inputFilePath);BufferedReader br = new BufferedReader(fr)) {// 使用FileWriter写入文件try (FileWriter fw = new FileWriter(outputFilePath);BufferedWriter bw = new BufferedWriter(fw)) {String line;while ((line = br.readLine()) != null) {bw.write(line);bw.newLine(); // 写入换行符}System.out.println("File copied successfully!");} catch (IOException e) {System.err.println("Error writing to file: " + e.getMessage());}} catch (IOException e) {System.err.println("Error reading from file: " + e.getMessage());}}
}

代码说明

  1. try-with-resources:Java 7引入的语法糖,用于自动关闭实现了AutoCloseable接口的资源,如IO流。这样可以避免手动关闭流,减少代码量并提高安全性。
  2. 缓冲流BufferedInputStreamBufferedOutputStream(或BufferedReaderBufferedWriter)可以提高读写效率,尤其是在处理大文件时。
  3. 异常处理:捕获IOException并打印错误信息。

注意事项

  1. 文件路径:确保文件路径正确,文件存在(对于输入文件)或可写(对于输出文件)。
  2. 字符编码:在处理文本文件时,字符流会自动处理字符编码。如果需要处理特定编码,可以使用InputStreamReaderOutputStreamWriter指定编码。
  3. 资源管理:即使不使用try-with-resources,也应确保在finally块中关闭流,以避免资源泄漏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/881267.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java中awit和sleep的区别和线程安全性问题

awit和sleep的区别 从名称上来讲: awit:等待。 sleep:休眠。 从属关系上来讲: awit:awit这个方法是在对象上,只要是对象,就有这个方法 sleep:sleep是在Thread上,它是在线程上,是一个静态方法使用方式上来讲: awit只能够在同步代码中去使用 sleep可以在任意的地方中去使用从…

[PyTorch] DDP源码阅读

[PyTorch] DDP源码阅读PyTorch的DistributedDataParallel (DDP) 允许多台机器,多台GPU之间的数据并行。本文简单讲解DDP的流程,并从代码层面理解DDP如何访问底层的通信框架。DDP使用单机多进程来控制多个GPU。模型需要能放入单个GPU中。参考了PyTorch 源码解读之 DP & DD…

SQL注入之时间盲注

SQL注入之时间盲注 一、时间盲注原理 时间盲注技术的核心在于巧妙地运用数据库中的时间延迟函数(例如 MySQL 的 SLEEP() 函数或 PostgreSQL 的 PG_SLEEP() 函数)来验证注入条件的有效性。当注入条件成立时,数据库会执行这些延迟函数,从而导致页面响应时间显著增加;反之,若…

P2024 [NOI2001] 食物链(带权并查集)

这道题要用带权并查集,感觉没听懂只能先把自己能懂得写了; 数组b[i]表示i与根节点的关系,//0 : 同类 1:吃 2:被吃#include r1 == r2 && b[x] != b[y]说明x和y在同一集合,但他们与根节点的关系不是一样的,说明他们不是同类,是假话 #include<set> #includ…

2025苹果春季发布会前瞻:新品迭出,Apple Intelligence国行版即将上线!

随着2025年的到来,苹果公司的春季发布会也渐行渐近。作为科技行业的领军企业,苹果每一次的新品发布都备受瞩目。本次春季发布会,苹果预计会带来一系列令人期待的新品,同时,国行Mac用户也将迎来一个重大更新——Apple Intelligence功能的上线。随着2025年的到来,苹果公司的…

Python3测试框架unittest搭配自动化测试报告工具HTMLTestRunner

最近接触到Python的测试框架unittest, 浅浅的学习了一下。 unittest和HTMLTestRunner搭配,可以完成自动化测试的功能并生成自动化测试报告。 一. 简介Python内置的unittest模块,用于编写和执行单元测试。 HTMLTestRunner 是一个用于生成自动化测试报告的工具,扩展了 unittes…

毕业设计目前进度

毕业设计进度:基于VoIP的音频音协算法设计与实现 1、学习了MATLAB的使用并动手实践界面认识 变量命名 运算和程序结构 矩阵操作 绘制二维三维图形等 绘制波形图(或数据曲线图)通过学习matlab的使用,为编写代码和运行并检测音频质量打下基础,同时也学会了建立坐标轴并绘制图…

使用LM Studio部署DeepSeek 1.5B模型

下载LM Studio: https://installers.lmstudio.ai/win32/x64/0.3.9-6/LM-Studio-0.3.9-6-x64.exe 安装LM Studio: 略 打开LM Studio 设置语言启用内置代理,用于下载模型,否则大概率在Model Search中看不到模型信息,无法下载模型模型下载,两种方式: 第一种,通过LM Studio…

React—05—脚手架

使用npm全局下载create-react-app, 建议node>16。npm install create-react-app -g; 然后创建项目即可。create-react-app 项目名称 但是现在create-react-app有问题,有些库依赖的react18但是这个脚手架创建的默认是react19,而官方还没解决这个问题,建议用vite创建一…

2.9 CW 练时记录

前言 新的类型, 跟考试放的差不多的策略就行了 后面就是找时间复习, 然后找一下状态就好了 \(\rm{F}\) 看到这是个 \(\rm{C}\) 题, 先做这个 思路给定 \(p_{i, c}\) 表示位置 \(i\) 是字符 \(c\) 的概率, 确定 \(\displaystyle\sum_{c = 1}^{t} p_{i, c} = 1\) 一个有效的信息被…

SMU2025寒假训练周报2

这周状态其实不太好,很多时候心急总是卡简单题,中档题也有些难a,希望尽快调整 一.个人训练赛2 1. Linova and Kingdom 题目链接:Problem - C - Codeforces 每加一个点总体贡献就可能发生变化,那我们就处理每个点的贡献,将他的深度减去他孩子的总个数就是贡献,最后排序取…