先序: 学习编程语言要先学个轮廓,刚开始只用学核心的部分,一些细节、不常用的内容先放着,现用现查即可;把常用的东西弄熟练了在慢慢补充。
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 HelloWorldHelloWorldpublic static void main(String[] args)System.out.println("Hello, World!");
2.2 注释
Java 支持三种类型的注释:
///* ... *//** ... */
3. 数据类型
Java 的数据类型分为两大类:基本数据类型 (primitive types) 和引用数据类型 (reference types)。
3.1 基本数据类型
byteshortintlongfloatdoublecharboolean
int number = 10;
float pi = 3.14f;
char letter = 'A';
boolean isJavaFun = true;
3.2 引用数据类型
引用数据类型包括,String、Integer 等类 (class), 接口 (interface), 数组 (array),以及枚举 (enum)。
4. 运算符
Java 提供了丰富的运算符,包括:
+-*/%=+=-=*=/=%===!=><>=<=&&||!&|^~<<>>>>>
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. 遍历数组的方法
for
for
int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
inumbers[i]
forfor-each
for
int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
这种方法直接获取数组中的每个元素,语法简洁。
2. 遍历字符串的方法
for
for
String text = "Hello";
for (int i = 0; i < text.length(); i++) {
System.out.println(text.charAt(i));
}
charAt(i)i
forfor-each
forString
String text = "Hello";
for (char ch : text.toCharArray()) {
System.out.println(ch);
}
toCharArray()
Stream API
Stream API
String text = "Hello";
text.chars().forEach(c -> System.out.println((char) c));
chars()IntStreamintchar
3. 其他的遍历方法
Iterator
ListSetIterator
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
IteratorhasNext()next()
forEach
forEachMap
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. 数组
数组是相同数据类型的集合,可以存储固定大小的元素。
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; }
{}
示例
Runnable r = () -> System.out.println("Hello, World!");
r.run(); // 输出: Hello, World!
Consumer<String> printer = s -> System.out.println(s);
printer.accept("Hello, Lambda!"); // 输出: Hello, Lambda!
BinaryOperator<Integer> add = (a, b) -> a + b;
System.out.println(add.apply(5, 3)); // 输出: 8
Function<Integer, String> intToString = i -> {
String result = "Number: " + i;
return result;
};
System.out.println(intToString.apply(10)); // 输出: Number: 10
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
下面给的示例代码都是从控制台获取输入
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(); // 关闭 Scanner
}
}
常用方法:
nextLine()nextLine().charAt(0)nextInt()nextDouble()nextBoolean()hasNext()hasNextLine()close()
8.2 BufferedReader 类
BufferedReaderInputStreamReader
使用 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(); // 关闭 BufferedReader
}
}
常用方法:
readLine()close()
对比 Scanner 和 BufferedReader
相同点:
nextLine()readLine()
不同点:
ScannernextInt()nextDouble()BufferedReaderBufferedReaderScannerScannerBufferedReader
8.3 输出
将数据输出到控制台。
System.out.print()
// 输出内容到控制台,末尾没有换行
System.out.print("Hello");
System.out.print("World");
HelloWorld
System.out.println()
// 输出内容到控制台,并在内容后自动添加换行符。
System.out.println("Hello");
System.out.println("World");
Hello
World
System.out.printf()
// 使用格式化字符串输出内容,类似于 C 语言中的 `printf`。允许你使用格式说明符控制输出的格式。
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 常用格式说明符
%d%x%f%.2f%s%c%%%
总结
System.out.print()System.out.println()System.out.printf()
try-with-resourcestryAutoCloseableInputStreamOutputStreamConnectiontry-with-resourcestry
try-catchtry-catch
9、异常处理
1. 基本语法
try-catch
try {
// 可能引发异常的代码
} catch (ExceptionType e) {
// 异常处理代码
}
trytrycatchcatchExceptionTypee
2. 示例
public class TryCatchExample {
public static void main(String[] args) {
try {
int result = 10 / 0; // 这会引发 ArithmeticException
} catch (ArithmeticException e) {
System.out.println("发生了除以零的错误: " + e.getMessage());
}
}
}
tryArithmeticExceptioncatch
catch
catch
public class MultiCatchExample {
public static void main(String[] args) {
try {
int[] numbers = new int[5];
numbers[10] = 10; // 这会引发 ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组索引越界错误: " + e.getMessage());
} catch (Exception e) {
System.out.println("发生了其他异常: " + e.getMessage());
}
}
}
ArrayIndexOutOfBoundsExceptionException
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("无论如何,都会执行的代码");
}
}
}
tryfinally
5. 多重异常处理
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-resourcestryclose()tryclose()finally
try-with-resources
try (ResourceType resource = new ResourceType()) {
// 使用资源的代码
} catch (ExceptionType e) {
// 异常处理代码
}
ResourceTypeAutoCloseablejava.io.Closeableresourcetrytrycatchtry
示例
try-with-resources
try-with-resourcesBufferedReaderAutoCloseabletry-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());
}
}
}
BufferedReadertryclose()
多个资源
try-with-resources
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
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"))) {
// 使用 reader 和 gzipInputStream 进行操作
} catch (IOException e) {
System.out.println("发生了 IO 异常: " + e.getMessage());
}
}
}
BufferedReaderGZIPInputStreamtry
自定义资源
try-with-resourcesAutoCloseablejava.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());
}
}
}
CustomResourceAutoCloseabletry-with-resourcestry
try-with-resources
10、Java 集合框架
String
1. 创建与初始化
String()String(String original)String
2. 字符串操作
concat(String str)substring(int beginIndex)substring(int beginIndex, int endIndex)beginIndexendIndex
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)str[0]length()isEmpty()toCharArray()startsWith(String prefix)endsWith(String suffix)matches(String regex)
List
ListArrayListLinkedList
ArrayList
ArrayList
ArrayList
常用方法:
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
SetHashSetTreeSet
HashSet
HashSet
HashSet
常用方法:
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
常用方法:
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
MapHashMapTreeMap
HashMap
HashMap
HashMap
常用方法:
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
常用方法:
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
QueueLinkedListPriorityQueue
LinkedList
LinkedListQueue
- 双向链表:可以作为队列(FIFO)和双端队列(Deque)使用。
- 高效的插入和删除操作:时间复杂度为 O(1)。
常用方法:
add(E e)offer(E e)truefalseremove()poll()nullelement()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)。
LinkedList
add(E e)offer(E e)remove()poll()nullelement()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);
}
}
CollectionStream
Stream
StreamStream
1. 创建 Stream
1. 从 Collection 创建 Stream
List<String> list = Arrays.asList("A", "B", "C");
Stream<String> streamFromList = list.stream();
Set<String> set = new HashSet<>(Arrays.asList("X", "Y", "Z"));
Stream<String> streamFromSet = set.stream();
Queue<String> queue = new LinkedList<>(Arrays.asList("1", "2", "3"));
Stream<String> streamFromQueue = queue.stream();
2. 从数组创建 Stream
String[] array = {"One", "Two", "Three"};
Stream<String> streamFromArray = Arrays.stream(array);
3. 生成特定类型的 Stream
Stream<String> streamOfValues = Stream.of("A", "B", "C");
4. 创建字符流
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
Streamfilter(Predicate predicate)map(Function mapper)sorted()distinct()StreamforEach(Consumer action)collect(Collector collector)Streamreduce(T identity, BinaryOperator accumulator)count()
StreamStream.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); // 输出: 1, 2, 3, 5, 8
}
}
降序排序
Comparatorreversed()ComparatorreverseOrder()
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()) // 使用 reverseOrder() 实现降序
.forEach(System.out::println); // 输出: 8, 5, 3, 2, 1
}
}
自定义排序(示例)
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()Comparatorreversed()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");
// 过滤出以 "A" 开头的名字
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);
// 查找第一个以 "C" 开头的名字
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.io
1. 字节流
字节流是以字节为单位进行数据的输入和输出。Java通过两个顶层抽象类来处理字节流:
InputStreamOutputStream
1.1 InputStream
InputStream
FileInputStreamByteArrayInputStreamBufferedInputStream
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
FileOutputStreamByteArrayOutputStreamBufferedOutputStream
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通过两个顶层抽象类来处理字符流:
ReaderWriter
2.1 Reader
Reader
FileReaderBufferedReader
2.1.1 FileReader读取字符文件
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按行读取
BufferedReaderreadLine()
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
Writer
FileWriterBufferedWriter
2.2.1 FileWriter写入字符文件
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缓冲写入
BufferedWriternewLine()
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) // 使用默认字符编码(通常是UTF-8或平台默认编码)
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")) { // 指定字符编码为UTF-8
int data;
while ((data = isr.read()) != -1) {
System.out.print((char) data); // 输出读取的字符
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStreamInputStreamReader
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")) { // 指定字符编码为UTF-8
osw.write("你好,世界!"); // 写入字符数据
} catch (IOException e) {
e.printStackTrace();
}
}
}
OutputStreamWriterFileOutputStream
3. 字符编码
当处理国际化字符或不同语言的文本时,指定正确的字符编码非常重要。例如,UTF-8是一种常用的字符编码,可以表示世界上大多数语言中的字符。使用转换流可以确保在不同字符编码之间进行正确的转换。
常见字符编码
- UTF-8:可变长度字符编码,适合国际化。
- ISO-8859-1:一种单字节编码,仅能表示西欧语言的字符。
- GBK:中文字符编码。
4. InputStreamReader 和 OutputStreamWriter 的常见用途
InputStreamReaderOutputStreamWriter
5. 总结
- InputStreamReader 和 OutputStreamWriter 是Java中用于在字节流和字符流之间转换的工具,解决了字节流处理字符时的编码问题。
- 通过这些转换流,程序可以方便地读取和写入不同字符编码的文本文件,确保文本内容在不同平台之间的兼容性。