跳到主要内容
Java 入门教程 | 极客日志
Java java
Java 入门教程 综述由AI生成 介绍 Java 编程语言的基础知识,包括环境概述、基本语法、数据类型、运算符、控制流程语句。内容涵盖面向对象编程核心概念如类、接口、继承和多态,以及 Lambda 表达式的使用。此外还详细讲解了 Java 集合框架(List、Set、Map、Queue)、Stream API 流处理、异常处理机制以及文件输入输出操作,适合初学者系统掌握 Java 开发技能。
技术博主 发布于 2026/3/27 更新于 2026/6/2 31 浏览Java 入门教程
前言
学习编程语言要先学个轮廓,刚开始只用学核心的部分,一些细节、不常用的内容先放着,现用现查即可;把常用的东西弄熟练了在慢慢补充。
1. Java 概述
Java 是一种面向对象的编程语言,由 Sun Microsystems(现在的 Oracle)在 1995 年推出。Java 程序可以在任何支持 Java 虚拟机 (JVM) 的设备上运行。Java 的核心理念是'一次编写,到处运行'。
2. 基本语法
2.1 Java 程序结构
每个 Java 程序都由类 (class) 和方法 (method) 组成。以下是一个简单的 Java 程序示例:
public class HelloWorld {
public static void main (String[] args) {
System.out.println("Hello, World!" );
}
}
public class HelloWorld:定义一个名为 HelloWorld 的公共类。
public static void main(String[] args):主方法,是程序的入口点。
System.out.println("Hello, World!"):打印一行文本到控制台。
2.2 注释
Java 支持三种类型的注释:
单行注释:使用 //
多行注释:使用 /* ... */
文档注释:使用 /** ... */
3. 数据类型
Java 的数据类型分为两大类:基本数据类型 (primitive types) 和引用数据类型 (reference types)。
3.1 基本数据类型
整型 :byte, short, int, long
浮点型 :float, double
字符型 :char
布尔型 :boolean
int number = 10 ;
float pi = 3.14f ;
char letter ;
;
=
'A'
boolean
isJavaFun
=
true
3.2 引用数据类型 引用数据类型包括 String、Integer 等类 (class), 接口 (interface), 数组 (array),以及枚举 (enum)。
4. 运算符
算术运算符 :+, -, *, /, %
赋值运算符 :=, +=, -=, *=, /=, %=
比较运算符 :==, !=, >, <, >=, <=
逻辑运算符 :&&, ||, !
位运算符 :&, |, ^, ~, <<, >>, >>>
int a = 5 ;
int b = 10 ;
int sum = a + b;
boolean isEqual = (a == b);
5. 判断和循环
5.1 条件语句
if 语句 :用于条件判断
switch 语句 :用于多分支选择
if (a > b) {
System.out.println("a is greater than b" );
} else if (a < b) {
System.out.println("a is less than b" );
} else {
System.out.println("a is equal to b" );
}
switch (a) {
case 1 :
System.out.println("a is 1" );
break ;
case 2 :
System.out.println("a is 2" );
break ;
default :
System.out.println("a is not 1 or 2" );
}
5.2 循环语句
for 循环 :用于固定次数的循环
while 循环 :用于条件控制的循环
do-while 循环 :至少执行一次的循环
for (int i = 0 ; i < 5 ; i++) {
System.out.println(i);
}
int j = 0 ;
while (j < 5 ) {
System.out.println(j);
j++;
}
int k = 0 ;
do {
System.out.println(k);
k++;
} while (k < 5 );
5.3 常用遍历方法 在 Java 中,遍历数组和字符串是常见的操作。下面详细介绍几种常用的遍历方法。
1. 遍历数组的方法
1.1 使用 for 循环 int [] numbers = {1 , 2 , 3 , 4 , 5 };
for (int i = 0 ; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
这里的 i 是数组的索引,通过 numbers[i] 获取数组元素。
1.2 使用增强型 for 循环(for-each 循环) 增强型 for 循环简化了数组的遍历,不需要使用索引:
int [] numbers = {1 , 2 , 3 , 4 , 5 };
for (int number : numbers) {
System.out.println(number);
}
2. 遍历字符串的方法
2.1 使用 for 循环 字符串可以看作是字符数组,可以用 for 循环逐个字符地遍历:
String text = "Hello" ;
for (int i = 0 ; i < text.length(); i++) {
System.out.println(text.charAt(i));
}
charAt(i) 方法返回字符串中第 i 个字符。
2.2 使用增强型 for 循环(for-each 循环) 虽然增强型 for 循环不能直接用于 String,但可以将字符串转换为字符数组后进行遍历:
String text = "Hello" ;
for (char ch : text.toCharArray()) {
System.out.println(ch);
}
toCharArray() 方法将字符串转换为字符数组,然后进行遍历。
2.3 使用 Stream API 同样地,可以使用 Stream API 来遍历字符串:
String text = "Hello" ;
text.chars().forEach(c -> System.out.println((char ) c));
chars() 方法返回一个包含字符的 IntStream,需要将 int 类型转换为 char 类型。
3. 其他的遍历方法
3.1 使用迭代器(Iterator) 对于集合类(如 List、Set 等),可以使用 Iterator 进行遍历:
List<String> list = Arrays.asList("A" , "B" , "C" );
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
Iterator 提供了 hasNext() 和 next() 方法,用于顺序访问集合中的元素。
3.2 使用 forEach 方法 Java 8 引入的 forEach 方法可以直接用于遍历集合和 Map:
List<String> list = Arrays.asList("A" , "B" , "C" );
list.forEach(System.out::println);
Map<Integer, String> map = new HashMap <>();
map.put(1 , "One" );
map.put(2 , "Two" );
map.forEach((key, value) -> System.out.println(key + " = " + value));
这种方法语法简洁,尤其适合使用 Lambda 表达式进行处理。
6. 数组与 Lambda 表达式 数组是相同数据类型的集合,可以存储固定大小的元素。
int [] numbers = new int [5 ];
numbers[0 ] = 1 ;
numbers[1 ] = 2 ;
int [] primes = {2 , 3 , 5 , 7 , 11 };
System.out.println(primes[0 ]);
Java 的 Lambda 表达式是一种简化代码的功能,主要用于表示匿名函数。它是 Java 8 引入的特性,旨在提供一种更简洁的方式来创建实现了某个接口的对象,特别是对于函数式接口。函数式接口是只包含一个抽象方法的接口。
Lambda 表达式的基本语法 (parameters) -> expression
(parameters) -> { statements; }
parameters : 这是 Lambda 表达式的输入参数,可以省略类型声明。
-> : 这是 Lambda 运算符,将参数与表达式或语句块分隔开。
expression : 这是一个单一的表达式,Lambda 表达式将其返回。
statements : 如果 Lambda 表达式包含多个语句,则需要用 {} 包括起来。
示例 Function<Integer, String> intToString = i -> {
String result = "Number: " + i;
return result;
};
System.out.println(intToString.apply(10 ));
这个 Lambda 表达式实现了 Function 接口,包含多个语句,返回一个字符串。
BinaryOperator<Integer> add = (a, b) -> a + b;
System.out.println(add.apply(5 , 3 ));
这个 Lambda 表达式实现了 BinaryOperator 接口,它接受两个参数并返回它们的和。
Consumer<String> printer = s -> System.out.println(s);
printer.accept("Hello, Lambda!" );
这个 Lambda 表达式实现了 Consumer 接口,它接收一个参数并打印它。
Runnable r = () -> System.out.println("Hello, World!" );
r.run();
这个 Lambda 表达式实现了 Runnable 接口,它没有参数,并且打印出 'Hello, World!'。
7. 面向对象编程 面向对象编程 (OOP) 是 Java 的核心概念,以下是几个重要的面向对象概念:
7.1 接口 接口是一种抽象类型,定义了类必须实现的方法。接口中的所有方法默认都是抽象的(没有方法体),且所有字段默认都是 public static final。
interface Animal {
void eat () ;
void sleep () ;
}
class Dog implements Animal {
@Override
public void eat () {
System.out.println("Dog eats" );
}
@Override
public void sleep () {
System.out.println("Dog sleeps" );
}
}
public class Main {
public static void main (String[] args) {
Dog dog = new Dog ();
dog.eat();
dog.sleep();
}
}
7.2 抽象类 抽象类是不能被实例化的类,可以包含抽象方法和具体方法。抽象方法必须在子类中实现。
abstract class Animal {
abstract void makeSound () ;
public void sleep () {
System.out.println("Sleeping..." );
}
}
class Dog extends Animal {
@Override
public void makeSound () {
System.out.println("Bark" );
}
}
public class Main {
public static void main (String[] args) {
Dog dog = new Dog ();
dog.makeSound();
dog.sleep();
}
}
7.3 继承 继承是指一个类(子类)继承另一个类(父类)的属性和方法。子类可以扩展或重写父类的方法。
class Animal {
public void eat () {
System.out.println("Animal eats" );
}
}
class Dog extends Animal {
@Override
public void eat () {
System.out.println("Dog eats" );
}
}
public class Main {
public static void main (String[] args) {
Dog dog = new Dog ();
dog.eat();
}
}
7.4 多态 多态允许同一个接口在不同的实现中表现出不同的行为。它是通过方法重载和方法重写实现的。
class Animal {
public void makeSound () {
System.out.println("Some sound" );
}
}
class Dog extends Animal {
@Override
public void makeSound () {
System.out.println("Bark" );
}
}
class Cat extends Animal {
@Override
public void makeSound () {
System.out.println("Meow" );
}
}
public class Main {
public static void main (String[] args) {
Animal myDog = new Dog ();
Animal myCat = new Cat ();
myDog.makeSound();
myCat.makeSound();
}
}
8. 输入输出 (I/O) Java 的 I/O 库提供了丰富的类和接口,用于文件操作、数据流操作、网络通信等。
8.1 Scanner 类 Scanner 类是 Java 5 引入的,用于从各种输入源读取数据,例如控制台输入、文件、字符串等。它提供了一系列方便的方法来解析基本类型和字符串。
import java.util.Scanner;
public class ScannerExample {
public static void main (String[] args) {
Scanner scanner = new Scanner (System.in);
System.out.print("请输入您的名字:" );
String name = scanner.nextLine();
System.out.println("你好," + name + "!" );
System.out.print("请输入您的年龄:" );
int age = scanner.nextInt();
System.out.println("您 " + age + " 岁了!" );
scanner.close();
}
}
常用方法:
nextLine(): 读取一整行输入,返回一个字符串。
nextLine().charAt(0): 读取一行字符串中的第一个,一般用这个读取 char 类型变量。
nextInt(): 读取一个整数。
nextDouble(): 读取一个双精度浮点数。
nextBoolean(): 读取一个布尔值。
hasNext(): 检查是否有下一个输入。
hasNextLine(): 检查是否有下一行输入。
close(): 关闭 Scanner。
8.2 BufferedReader 类 BufferedReader 类用于从字符输入流中读取文本,提供了缓冲功能以提高读取效率。它通常与 InputStreamReader 一起使用,从标准输入或文件读取数据。
使用 BufferedReader 从终端读取数据
示例代码: import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BufferedReaderExample {
public static void main (String[] args) throws IOException {
BufferedReader reader = new BufferedReader (new InputStreamReader (System.in));
System.out.print("请输入您的名字:" );
String name = reader.readLine();
System.out.println("你好," + name + "!" );
System.out.print("请输入您的年龄:" );
int age = Integer.parseInt(reader.readLine());
System.out.println("您 " + age + " 岁了!" );
reader.close();
}
}
常用方法:
readLine(): 读取一整行输入,返回一个字符串。
close(): 关闭 BufferedReader。
对比 Scanner 和 BufferedReader
相同点:
都可以用于从终端、文件等源读取输入。
都提供了读取整行输入的方法:nextLine() 和 readLine()。
不同点:
功能 :
Scanner 提供了更多解析输入数据的方法,如 nextInt(), nextDouble() 等,可以直接读取基本类型数据。
BufferedReader 主要用于读取字符串,需要手动解析基本类型数据。
性能 :
BufferedReader 通常性能更高,因为它使用缓冲机制,适合读取大量文本数据。
Scanner 在方便性上有优势,但性能可能稍逊色。
使用场景 :
Scanner 更适合处理交互式的终端输入,或者需要解析各种基本类型数据的场景。
BufferedReader 更适合读取大量文本数据,或者需要更高效的输入操作的场景。
8.3 输出
1. System.out.print()
System.out.print("Hello" );
System.out.print("World" );
2. System.out.println()
System.out.println("Hello" );
System.out.println("World" );
3. System.out.printf()
用法 : System.out.printf(formatString, arguments);
int age = 25 ;
double height = 1.75 ;
System.out.printf("Age: %d years\n" , age);
System.out.printf("Height: %.2f meters\n" , height);
Age: 25 years Height : 1.75 meters
8.4 常用格式说明符
总结
System.out.print() : 用于输出内容,不换行。
System.out.println() : 用于输出内容并换行。
System.out.printf() : 用于格式化输出内容。
try-with-resources 语句(通常被称为 try 语句)是 Java 7 引入的一个特性,它简化了资源管理,特别是用于自动关闭实现了 AutoCloseable 接口的资源,如 InputStream、OutputStream、Connection 等。try-with-resources 语句保证在 try 块执行完毕后,即使发生异常,资源也会被自动关闭。
当然!在 Java 中,try-catch 语句用于处理异常。异常是程序运行过程中发生的错误或不预期的情况,try-catch 块允许你捕获和处理这些异常,以避免程序崩溃并提供更好的用户体验。
9. 异常处理
1. 基本语法 try {
} catch (ExceptionType e) {
}
try 块 : 包含可能会引发异常的代码。如果 try 块中的代码引发了异常,异常会被 catch 块捕获。
catch 块 : 用于处理异常的代码。ExceptionType 是你要捕获的异常类型,e 是异常对象,可以用来获取异常的详细信息。
2. 示例 public class TryCatchExample {
public static void main (String[] args) {
try {
int result = 10 / 0 ;
} catch (ArithmeticException e) {
System.out.println("发生了除以零的错误:" + e.getMessage());
}
}
}
在这个示例中,try 块中的代码试图执行一个除以零的操作,导致 ArithmeticException 异常。catch 块捕获这个异常,并输出错误消息。
3. 多个 catch 块 你可以有多个 catch 块来处理不同类型的异常:
public class MultiCatchExample {
public static void main (String[] args) {
try {
int [] numbers = new int [5 ];
numbers[10 ] = 10 ;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组索引越界错误:" + e.getMessage());
} catch (Exception e) {
System.out.println("发生了其他异常:" + e.getMessage());
}
}
}
在这个示例中,ArrayIndexOutOfBoundsException 异常被单独捕获,而其他任何类型的异常都可以被通用的 Exception 捕获。
4. finally 块 finally 块用于执行清理代码,无论是否发生异常,它都会执行。通常用于关闭文件、释放资源等操作。
public class FinallyExample {
public static void main (String[] args) {
try {
System.out.println("尝试打开文件" );
} catch (Exception e) {
System.out.println("处理异常:" + e.getMessage());
} finally {
System.out.println("无论如何,都会执行的代码" );
}
}
}
在这个示例中,无论 try 块中是否发生异常,finally 块中的代码都会执行。
5. 多重异常处理 Java 7 引入了多重异常捕获(多异常捕获),你可以在一个 catch 块中捕获多种异常类型,并用 | 分隔它们:
public class MultiExceptionCatchExample {
public static void main (String[] args) {
try {
} catch (IOException | SQLException e) {
System.out.println("发生了 IO 或 SQL 异常:" + e.getMessage());
}
}
}
6. 重新抛出异常 在 catch 块中,你可以选择重新抛出异常,以便在更高的层次处理它:
public class RethrowExceptionExample {
public static void main (String[] args) {
try {
methodThatThrowsException();
} catch (Exception e) {
System.out.println("捕获异常:" + e.getMessage());
throw e;
}
}
public static void methodThatThrowsException () throws Exception {
throw new Exception ("这是一个异常" );
}
}
在这个示例中,异常在 catch 块中被捕获并重新抛出,允许调用方法的代码进一步处理异常。
7. try-with-resources try-with-resources 语句在 try 块执行完毕后,会自动调用每个资源的 close() 方法。即使在 try 块中发生了异常,资源的 close() 方法也会被调用。因此,你不需要在 finally 块中显式地关闭资源,这样可以减少代码重复并提高代码的可读性。
try-with-resources 语句的基本语法如下:
try (ResourceType resource = new ResourceType ()) {
} catch (ExceptionType e) {
}
**ResourceType**: 实现了 AutoCloseable 或 java.io.Closeable 接口的资源类型。
**resource**: 在 try 块中使用的资源对象。
try 块 : 包含使用资源的代码。
catch 块 : 处理在 try 块中可能发生的异常。
示例
使用 try-with-resources 关闭文件 以下是一个使用 try-with-resources 读取文件内容的示例。BufferedReader 实现了 AutoCloseable 接口,因此可以被用于 try-with-resources 语句中:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main (String[] args) {
try (BufferedReader reader = new BufferedReader (new FileReader ("file.txt" ))) {
String line;
while ((line = reader.readLine()) != null ) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("读取文件时发生错误:" + e.getMessage());
}
}
}
在这个示例中,BufferedReader 会在 try 块执行完成后自动关闭,无需显式调用 close() 方法。
多个资源 你也可以在 try-with-resources 语句中管理多个资源,这些资源会按照声明的顺序关闭:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.zip.GZIPInputStream;
public class MultipleResourcesExample {
public static void main (String[] args) {
try (BufferedReader reader = new BufferedReader (new FileReader ("file.txt" ));
GZIPInputStream gzipInputStream = new GZIPInputStream (new FileInputStream ("file.txt.gz" ))) {
} catch (IOException e) {
System.out.println("发生了 IO 异常:" + e.getMessage());
}
}
}
在这个示例中,BufferedReader 和 GZIPInputStream 会在 try 块执行完成后自动关闭。
自定义资源 如果你定义了一个自定义类,并希望它在 try-with-resources 中使用,那么这个类需要实现 AutoCloseable 接口(或者 java.io.Closeable 接口)。例如:
public class CustomResource implements AutoCloseable {
@Override
public void close () {
System.out.println("CustomResource closed" );
}
public void doSomething () {
System.out.println("Doing something with CustomResource" );
}
public static void main (String[] args) {
try (CustomResource resource = new CustomResource ()) {
resource.doSomething();
} catch (Exception e) {
System.out.println("发生了异常:" + e.getMessage());
}
}
}
在这个示例中,CustomResource 实现了 AutoCloseable 接口,因此可以在 try-with-resources 中使用,并在 try 块结束后自动关闭。
try-with-resources 语句使得资源管理变得更加简单、安全,特别是当涉及到需要手动关闭的资源时。
10. Java 集合框架
String
1. 创建与初始化
String() :创建一个空字符串。
String(String original) :创建一个新的字符串,内容为指定的 String。
2. 字符串操作
concat(String str) :连接指定字符串到当前字符串末尾。
substring(int beginIndex) :从指定索引开始,返回子字符串。
substring(int beginIndex, int endIndex) :返回从 beginIndex 到 endIndex 之间的子字符串。
3. 查找与比较
indexOf(String str) :返回指定子字符串第一次出现的索引。
lastIndexOf(String str) :返回指定子字符串最后一次出现的索引。
contains(CharSequence sequence) :判断当前字符串是否包含指定字符序列。
equals(Object anObject) :比较两个字符串的内容是否相等。
equalsIgnoreCase(String anotherString) :忽略大小写比较两个字符串的内容是否相等。
compareTo(String anotherString) :按字典顺序比较两个字符串。
4. 替换与转换
replace(char oldChar, char newChar) :替换字符串中的所有指定字符为新字符。
replaceAll(String regex, String replacement) :用正则表达式匹配并替换匹配的部分。
toLowerCase() :将字符串转换为小写。
toUpperCase() :将字符串转换为大写。
trim() :去除字符串首尾的空白字符。
5. 分割与连接
split(String regex) :根据正则表达式分割字符串,返回字符串数组。
join(CharSequence delimiter, CharSequence... elements) :使用指定的分隔符连接多个字符序列。
6. 其他
charAt(int index) :返回指定索引处的字符。java 的 String 不可以通过 str[0] 这样的方式访问
length() :返回字符串的长度。
isEmpty() :判断字符串是否为空(长度为 0)。
toCharArray() :将字符串转换为字符数组。
startsWith(String prefix) :判断字符串是否以指定的前缀开始。
endsWith(String suffix) :判断字符串是否以指定的后缀结束。
matches(String regex) :判断字符串是否匹配给定的正则表达式。
List List 是一个有序的集合,可以包含重复元素。常用实现类有 ArrayList 和 LinkedList。
ArrayList ArrayList 是一个基于动态数组的数据结构,提供了快速的随机访问能力。它的主要特点是:
动态调整数组大小:当元素超过数组容量时,ArrayList 会自动扩展。
访问元素速度快:由于底层是数组,通过索引访问元素的时间复杂度为 O(1)。
插入和删除操作相对较慢:插入或删除元素时,可能需要移动数组中的其他元素,时间复杂度为 O(n)。
add(E e): 添加元素到列表末尾。
get(int index): 获取指定索引位置的元素。
set(int index, E element): 替换指定索引位置的元素。
remove(int index): 移除指定索引位置的元素。
size(): 返回列表中元素的数量。
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main (String[] args) {
List<String> list = new ArrayList <>();
list.add("Apple" );
list.add("Banana" );
list.add("Cherry" );
System.out.println("List: " + list);
System.out.println("Element at index 1: " + list.get(1 ));
list.set(1 , "Blueberry" );
System.out.println("Updated List: " + list);
list.remove(0 );
System.out.println("List after removal: " + list);
}
}
LinkedList LinkedList 是一个基于双向链表的数据结构,提供了高效的插入和删除操作。它的主要特点是:
链表节点:每个元素都是一个节点,包含元素值以及指向前一个和后一个节点的指针。
插入和删除速度快:插入和删除元素时只需调整指针,时间复杂度为 O(1)。
访问元素速度慢:由于需要从头开始遍历链表,通过索引访问元素的时间复杂度为 O(n)。
add(E e): 添加元素到列表末尾。
get(int index): 获取指定索引位置的元素。
set(int index, E element): 替换指定索引位置的元素。
remove(int index): 移除指定索引位置的元素。
size(): 返回列表中元素的数量。
import java.util.LinkedList;
import java.util.List;
public class LinkedListExample {
public static void main (String[] args) {
List<String> list = new LinkedList <>();
list.add("Apple" );
list.add("Banana" );
list.add("Cherry" );
System.out.println("List: " + list);
System.out.println("Element at index 1: " + list.get(1 ));
list.set(1 , "Blueberry" );
System.out.println("Updated List: " + list);
list.remove(0 );
System.out.println("List after removal: " + list);
}
}
Set Set 是一个不包含重复元素的集合。常用实现类有 HashSet 和 TreeSet。
HashSet HashSet 基于哈希表实现,元素没有顺序。它的主要特点是:
无序集合:元素没有特定的顺序。
不允许重复元素:如果添加重复元素,HashSet 会忽略它。
高效的插入、删除和查找操作:时间复杂度为 O(1)。
add(E e): 添加元素到集合中。
remove(Object o): 从集合中移除指定元素。
contains(Object o): 检查集合是否包含指定元素。
size(): 返回集合中元素的数量。
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main (String[] args) {
Set<String> set = new HashSet <>();
set.add("Apple" );
set.add("Banana" );
set.add("Cherry" );
set.add("Apple" );
System.out.println("Set: " + set);
System.out.println("Set contains 'Banana': " + set.contains("Banana" ));
set.remove("Banana" );
System.out.println("Set after removal: " + set);
}
}
TreeSet TreeSet 基于红黑树实现,元素是有序的。它的主要特点是:
有序集合:元素按照自然顺序或自定义顺序排序。
不允许重复元素:如果添加重复元素,TreeSet 会忽略它。
较高的插入、删除和查找操作性能:时间复杂度为 O(log n)。
add(E e): 添加元素到集合中。
remove(Object o): 从集合中移除指定元素。
contains(Object o): 检查集合是否包含指定元素。
size(): 返回集合中元素的数量。
import java.util.Set;
import java.util.TreeSet;
public class TreeSetExample {
public static void main (String[] args) {
Set<String> set = new TreeSet <>();
set.add("Banana" );
set.add("Apple" );
set.add("Cherry" );
System.out.println("Set: " + set);
System.out.println("Set contains 'Banana': " + set.contains("Banana" ));
set.remove("Banana" );
System.out.println("Set after removal: " + set);
}
}
Map Map 是一个键值对的集合,每个键最多只能关联一个值。常用实现类有 HashMap 和 TreeMap。
HashMap HashMap 基于哈希表实现,键值对没有顺序。它的主要特点是:
无序集合:键值对没有特定的顺序。
不允许重复键:如果添加重复键,HashMap 会覆盖旧值。
高效的插入、删除和查找操作:时间复杂度为 O(1)。
put(K key, V value): 添加键值对到映射中。
get(Object key): 获取指定键的值。
remove(Object key): 从映射中移除指定键值对。
containsKey(Object key): 检查映射是否包含指定键。
size(): 返回映射中键值对的数量。
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main (String[] args) {
Map<String, Integer> map = new HashMap <>();
map.put("Apple" , 1 );
map.put("Banana" , 2 );
map.put("Cherry" , 3 );
System.out.println("Map: " + map);
System.out.println("Value for 'Banana': " + map.get("Banana" ));
map.remove("Banana" );
System.out.println("Map after removal: " + map);
}
}
TreeMap TreeMap 基于红黑树实现,键值对是有序的。它的主要特点是:
有序集合:键值对按照键的自然顺序或自定义顺序排序。
不允许重复键:如果添加重复键,TreeMap 会覆盖旧值。
较高的插入、删除和查找操作性能:时间复杂度为 O(log n)。
put(K key, V value): 添加键值对到映射中。
get(Object key): 获取指定键的值。
remove(Object key): 从映射中移除指定键值对。
containsKey(Object key): 检查映射是否包含指定键。
size(): 返回映射中键值对的数量。
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main (String[] args) {
Map<String, Integer> map = new TreeMap <>();
map.put("Banana" , 2 );
map.put("Apple" , 1 );
map.put("Cherry" , 3 );
System.out.println("Map: " + map);
System.out.println("Value for 'Banana': " + map.get("Banana" ));
map.remove("Banana" );
System.out.println("Map after removal: " + map);
}
}
Queue Queue 是一个先进先出的集合,常用实现类有 LinkedList 和 PriorityQueue。
LinkedList LinkedList 实现了 Queue 接口,提供了基于链表的队列实现。它的主要特点是:
双向链表:可以作为队列(FIFO)和双端队列(Deque)使用。
高效的插入和删除操作:时间复杂度为 O(1)。
add(E e): 将指定元素插入此队列的末尾。
offer(E e): 将指定元素插入此队列的末尾,如果成功则返回 true,如果队列已满则返回 false(一般不检查队列是否满)。
remove(): 检索并移除此队列的头部元素。
poll(): 检索并移除此队列的头部元素,如果此队列为空,则返回 null。
element(): 检索但不移除此队列的头部元素。
peek(): 检索但不移除此队列的头部元素,如果此队列为空,则返回 null。
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main (String[] args) {
Queue<String> queue = new LinkedList <>();
queue.add("Apple" );
queue.offer("Banana" );
queue.add("Cherry" );
System.out.println("Queue: " + queue);
System.out.println("Head of the queue: " + queue.peek());
queue.remove();
System.out.println("Queue after removal: " + queue);
queue.poll();
System.out.println("Queue after poll: " + queue);
}
}
PriorityQueue PriorityQueue 是一个基于优先级堆(最小堆或最大堆)的队列,元素按自然顺序或自定义顺序排序。它的主要特点是:
无界优先级队列:元素按照优先级排序,不一定是先进先出(FIFO)。
默认最小堆:自然顺序为最小堆,可自定义比较器实现最大堆。
高效的插入和删除操作:时间复杂度为 O(log n)。
add(E e): 将指定元素插入此队列。
offer(E e): 将指定元素插入此队列。
remove(): 检索并移除此队列的头部元素。
poll(): 检索并移除此队列的头部元素,如果此队列为空,则返回 null。
element(): 检索但不移除此队列的头部元素。
peek(): 检索但不移除此队列的头部元素,如果此队列为空,则返回 null。
import java.util.PriorityQueue;
import java.util.Queue;
public class PriorityQueueExample {
public static void main (String[] args) {
Queue<String> queue = new PriorityQueue <>();
queue.add("Banana" );
queue.offer("Apple" );
queue.add("Cherry" );
System.out.println("PriorityQueue: " + queue);
System.out.println("Head of the queue: " + queue.peek());
queue.remove();
System.out.println("PriorityQueue after removal: " + queue);
queue.poll();
System.out.println("PriorityQueue after poll: " + queue);
}
}
Stream Stream 是 Java 8 引入的一个新特性,它提供了一种功能性编程风格来处理集合数据。Stream 并不存储数据,而是对数据进行操作的工具。
1. 创建 Stream
1. 从 Collection 创建 Stream Queue : 使用 stream() 方法创建 Stream。
Queue<String> queue = new LinkedList <>(Arrays.asList("1" , "2" , "3" ));
Stream<String> streamFromQueue = queue.stream();
Set : 使用 stream() 方法创建 Stream。
Set<String> set = new HashSet <>(Arrays.asList("X" , "Y" , "Z" ));
Stream<String> streamFromSet = set.stream();
List : 使用 stream() 方法创建 Stream。
List<String> list = Arrays.asList("A" , "B" , "C" );
Stream<String> streamFromList = list.stream();
2. 从数组创建 Stream 数组 : 使用 Arrays.stream() 方法将数组转换为 Stream。
String[] array = {"One" , "Two" , "Three" };
Stream<String> streamFromArray = Arrays.stream(array);
3. 生成特定类型的 Stream Stream.of() : 创建包含指定元素的 Stream。
Stream<String> streamOfValues = Stream.of("A" , "B" , "C" );
4. 创建字符流 Files.lines() : 从文件中创建字符流。
Path path = Paths.get("file.txt" );
try (Stream<String> lines = Files.lines(path)) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
2. Stream 操作 Stream 支持多种操作,可以分为中间操作和终端操作:
中间操作 : 返回一个新的 Stream,可以链式调用,常用的中间操作有:
filter(Predicate<T> predicate): 过滤流中的元素。
map(Function<T, R> mapper): 将元素映射成另一种形式。
sorted(): 对流进行排序。
distinct(): 去重操作。
终端操作 : 触发对 Stream 的处理并生成结果,常用的终端操作有:
forEach(Consumer<T> action): 遍历每个元素并执行操作。
collect(Collector<T, A, R> collector): 将 Stream 收集到集合中。
reduce(T identity, BinaryOperator<T> accumulator): 对流中的元素进行归约操作。
count(): 计算流中元素的数量。
在 Java 的 Stream API 中,Stream.sorted() 方法默认按照升序对流中的元素进行排序。你可以通过使用 Comparator 进行自定义排序来控制排序顺序,包括降序排序。
3. sorted Stream.sorted() 方法在没有参数的情况下会使用元素的自然顺序(如果元素实现了 Comparable 接口),即默认进行升序排序。例如:
import java.util.Arrays;
import java.util.List;
public class StreamSortExample {
public static void main (String[] args) {
List<Integer> numbers = Arrays.asList(5 , 3 , 8 , 1 , 2 );
numbers.stream()
.sorted()
.forEach(System.out::println);
}
}
降序排序 要实现降序排序,你可以使用 Comparator 的 reversed() 方法,或者使用 Comparator 的 reverseOrder() 方法。以下是如何进行降序排序的示例:
使用 Comparator.reversed() import java.util.Arrays;
import java.util.List;
import java.util.Comparator;
public class StreamSortExample {
public static void main (String[] args) {
List<Integer> numbers = Arrays.asList(5 , 3 , 8 , 1 , 2 );
numbers.stream()
.sorted(Comparator.reverseOrder())
.forEach(System.out::println);
}
}
自定义排序(示例) 如果你需要对复杂对象进行降序排序,可以使用自定义的 Comparator:
import java.util.Arrays;
import java.util.List;
import java.util.Comparator;
public class StreamSortExample {
public static void main (String[] args) {
List<Person> people = Arrays.asList(
new Person ("Alice" , 30 ),
new Person ("Bob" , 25 ),
new Person ("Charlie" , 30 ),
new Person ("David" , 25 )
);
people.stream()
.sorted(Comparator.comparingInt(Person::getAge).reversed().thenComparing(Person::getName))
.forEach(person -> System.out.println(person.getName() + ": " + person.getAge()));
}
static class Person {
private String name;
private int age;
Person(String name, int age) {
this .name = name;
this .age = age;
}
public String getName () {
return name;
}
public int getAge () {
return age;
}
}
}
总结
默认排序 :Stream.sorted() 默认按照升序对元素进行排序。
降序排序 :使用 Comparator.reverseOrder() 或 Comparator 的 reversed() 方法进行降序排序。
自定义排序 :可以结合使用 Comparator 的不同方法来实现更复杂的排序需求,例如同时按多个字段排序。
4. Stream 示例 import java.util.*;
import java.util.stream.Collectors;
public class StreamExample {
public static void main (String[] args) {
List<String> names = Arrays.asList("Alice" , "Bob" , "Charlie" , "David" );
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A" ))
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("Filtered Names: " + filteredNames);
int totalLength = names.stream()
.mapToInt(String::length)
.sum();
System.out.println("Total Length: " + totalLength);
Optional<String> firstNameStartingWithC = names.stream()
.filter(name -> name.startsWith("C" ))
.findFirst();
firstNameStartingWithC.ifPresent(name -> System.out.println("First Name Starting with C: " + name));
}
}
11. 对文件的操作 Java 中,输入输出流(I/O 流)是处理数据输入和输出的关键机制。它们用于读取和写入数据,支持处理字节流和字符流。Java I/O 流可以分为两大类:
字节流(Byte Streams) :处理原始字节的数据流,如图片、音频、视频文件。
字符流(Character Streams) :专门处理字符数据,如文本文件。
Java 的输入输出流主要位于 java.io 包中。下面详细讲解如何使用 Java 的 I/O 流进行文件、控制台、网络等输入输出操作。
1. 字节流 字节流是以字节为单位进行数据的输入和输出。Java 通过两个顶层抽象类来处理字节流:
InputStream :所有字节输入流的基类。
OutputStream :所有字节输出流的基类。
1.1 InputStream InputStream 是读取字节数据的基础类,常用子类包括:
FileInputStream :从文件中读取字节数据。
ByteArrayInputStream :从内存中的字节数组读取数据。
BufferedInputStream :提供缓冲功能,提高读取效率。
1.1.1 FileInputStream 读取文件 FileInputStream 用于从文件中读取字节数据。以下是读取文件的示例:
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamExample {
public static void main (String[] args) {
try (FileInputStream fis = new FileInputStream ("example.txt" )) {
int byteData;
while ((byteData = fis.read()) != -1 ) {
System.out.print((char ) byteData);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.1.2 BufferedInputStream 缓冲读取 BufferedInputStream 提供缓冲区,减少对文件的访问次数,提高读取效率。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class BufferedInputStreamExample {
public static void main (String[] args) {
try (BufferedInputStream bis = new BufferedInputStream (new FileInputStream ("example.txt" ))) {
int byteData;
while ((byteData = bis.read()) != -1 ) {
System.out.print((char ) byteData);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.2 OutputStream OutputStream 用于写入字节数据,常用子类包括:
FileOutputStream :向文件中写入字节数据。
ByteArrayOutputStream :将数据写入内存中的字节数组。
BufferedOutputStream :提供缓冲功能,提高写入效率。
1.2.1 FileOutputStream 写入文件 FileOutputStream 用于向文件中写入字节数据。如果文件不存在,它会创建文件。
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamExample {
public static void main (String[] args) {
try (FileOutputStream fos = new FileOutputStream ("output.txt" )) {
String data = "Hello, FileOutputStream!" ;
fos.write(data.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.2.2 BufferedOutputStream 缓冲写入 BufferedOutputStream 提供缓冲区,可以提高写入效率。
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamExample {
public static void main (String[] args) {
try (BufferedOutputStream bos = new BufferedOutputStream (new FileOutputStream ("output.txt" ))) {
String data = "Hello, BufferedOutputStream!" ;
bos.write(data.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. 字符流 字符流用于处理字符数据,专门设计为以字符为单位进行输入输出。Java 通过两个顶层抽象类来处理字符流:
Reader :所有字符输入流的基类。
Writer :所有字符输出流的基类。
2.1 Reader
FileReader :从文件中读取字符。
BufferedReader :提供缓冲功能,并且提供按行读取的能力。
2.1.1 FileReader 读取字符文件 import java.io.FileReader;
import java.io.IOException;
public class FileReaderExample {
public static void main (String[] args) {
try (FileReader fr = new FileReader ("example.txt" )) {
int charData;
while ((charData = fr.read()) != -1 ) {
System.out.print((char ) charData);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.1.2 BufferedReader 按行读取 BufferedReader 不仅提供缓冲功能,还提供 readLine() 方法用于按行读取文件内容。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderExample {
public static void main (String[] args) {
try (BufferedReader br = new BufferedReader (new FileReader ("example.txt" ))) {
String line;
while ((line = br.readLine()) != null ) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.2 Writer
FileWriter :向文件中写入字符数据。
BufferedWriter :提供缓冲功能,并且提供按行写入的能力。
2.2.1 FileWriter 写入字符文件 import java.io.FileWriter;
import java.io.IOException;
public class FileWriterExample {
public static void main (String[] args) {
try (FileWriter fw = new FileWriter ("output.txt" )) {
fw.write("Hello, FileWriter!" );
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.2.2 BufferedWriter 缓冲写入 BufferedWriter 不仅提供缓冲区,还提供 newLine() 方法,用于写入换行符。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterExample {
public static void main (String[] args) {
try (BufferedWriter bw = new BufferedWriter (new FileWriter ("output.txt" ))) {
bw.write("Hello, BufferedWriter!" );
bw.newLine();
bw.write("This is a new line." );
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 转换流(Character Streams) 转换流用于在字节流和字符流之间进行转换,主要用于处理不同的字符编码。Java 提供了两个主要的转换流类:
InputStreamReader :将字节流转换为字符流(从输入字节流读取数据,并将其转换为字符)。
OutputStreamWriter :将字符流转换为字节流(将字符数据写出时转换为字节)。
1. InputStreamReader InputStreamReader 是一个将字节流转换为字符流的桥梁。它读取来自字节流的数据,并根据指定的字符编码将其转换为字符数据。
InputStreamReader 的构造方法 InputStreamReader(InputStream in)
InputStreamReader(InputStream in, String charsetName)
示例:使用 InputStreamReader 以下是使用 InputStreamReader 从字节流中读取字符的示例:
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
public class InputStreamReaderExample {
public static void main (String[] args) {
try (FileInputStream fis = new FileInputStream ("example.txt" );
InputStreamReader isr = new InputStreamReader (fis, "UTF-8" )) {
int data;
while ((data = isr.read()) != -1 ) {
System.out.print((char ) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
工作原理 :FileInputStream 以字节的形式读取文件内容,而 InputStreamReader 将字节数据转换为字符数据。
2. OutputStreamWriter OutputStreamWriter 是将字符流转换为字节流的桥梁。它接收字符数据,并根据指定的字符编码将其转换为字节流输出。
OutputStreamWriter 的构造方法 OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, String charsetName)
示例:使用 OutputStreamWriter 以下是使用 OutputStreamWriter 将字符数据写入字节流的示例:
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
public class OutputStreamWriterExample {
public static void main (String[] args) {
try (FileOutputStream fos = new FileOutputStream ("output.txt" );
OutputStreamWriter osw = new OutputStreamWriter (fos, "UTF-8" )) {
osw.write("你好,世界!" );
} catch (IOException e) {
e.printStackTrace();
}
}
}
工作原理 :OutputStreamWriter 接收字符数据,并根据 UTF-8 编码转换为字节,最后通过 FileOutputStream 将其写入文件中。
3. 字符编码 当处理国际化字符或不同语言的文本时,指定正确的字符编码非常重要。例如,UTF-8 是一种常用的字符编码,可以表示世界上大多数语言中的字符。使用转换流可以确保在不同字符编码之间进行正确的转换。
常见字符编码
UTF-8 :可变长度字符编码,适合国际化。
ISO-8859-1 :一种单字节编码,仅能表示西欧语言的字符。
GBK :中文字符编码。
4. InputStreamReader 和 OutputStreamWriter 的常见用途
读取文件内容并指定编码 :当处理包含特殊字符的文件时,使用 InputStreamReader 可以正确处理字符数据。
写入文件内容并指定编码 :使用 OutputStreamWriter 可以将字符流以特定编码方式写入文件,确保跨平台的字符一致性。
网络通信中的字符转换 :在网络应用中,传输的数据往往是字节流,但客户端和服务器端可能使用不同的字符编码,因此需要使用转换流来处理。
5. 总结
InputStreamReader 和 OutputStreamWriter 是 Java 中用于在字节流和字符流之间转换的工具,解决了字节流处理字符时的编码问题。
通过这些转换流,程序可以方便地读取和写入不同字符编码的文本文件,确保文本内容在不同平台之间的兼容性。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online