Java学习整理
java基础
数组
//声明方式:类型[] 变量;
//数组的创建:new 类型[容量];
String[] names = new String[10];
// 给数组添加数据,添加的方式为:数组变量[索引] = 数据;
// 添加数据和访问数据时,索引不能超过指定范围(0~length-1)
// 重复给相同索引添加数据,等同于修改
names[0]="zhangsan";
// 查询(访问)数据的方式:数组变量[索引];
System.out.println(names[0]);
//对象数组
User[] user = new User[3];
for(int i = 0;i<3;i++)//可以直接用 user.length替换3
{
user[i] = new User;
}
for(int i = 0;i<3;i++)
{
user[i].test();
}
二维数组
Java中的二维数组更像是一种引用,并不是严格的方阵
String[][] nums = new String[3][3];
字符串
字符串的截断操作
截取字符串(substring)
1.
String s = "Hello World";
//子字符串
s.substring(0,3);//从第一个字符开始,到下标为3的字符,但不包括该位置
/*
substring 方法用于截取字符串,需要传递两个参数:
第一个参数表示截取字符串的起始位置(索引,包含)
第二个参数表示截取字符串的结束位置(索引,不包含)
*/
s.substring(0,"Hello".length);//截取Hello
2.
s.substring(6);
//只传递一个参数表示从指定位置开始截取字符串,然后截取到最后
分解字符串(split)
返回数组
//根据指定的规则对字符串进行分解,可以将一个完整的字符串,分解成几部分
String[] s1 = s.split(" ");
去掉空格(trim)
去掉字符串的首位空格,字符串中间的空格不做处理
String s=" hh hh ";
sout(s.trim());
==>hh hh
字符串的替换
replace
纯粹的替换
String s = "Hello World";
s.replace("World","java");
replaceAll
按照规则替换
String s = "Hello World Zhangsan";
s.replace("World|Zhangsan","java");//将World与Zhangsan都替换成java
字符串的大小写转换
转小写(toLowerCase)
s.toLowerCase();//全部转小写
转大写(toUpperCase)
s.toUpperCase();//全部转大写
字符串的查找
char[] chars = s.toCharArray();//将字符串拆分成字符数组
byte[] bytes = s.getBytes("UTF-8");//将字符串拆分成utf-8字节码
s.charAt(索引号);//传递索引定位字符串中指定位置的字符
s.indexOf(" ");//用于获取数据在字符串中第一次出现的位置
s.lastIndexOf(" ");//用于获取数据在字符串中最后一次出现的位置
s.contains(" ");//用于判断字符串中有没有出现过该数据,boolean类型
s.startsWith(" ")//判断字符串是否以指定的数据开头,boolean类型
s.endsWith("");//判断字符串是否以指定数据结尾,boolean类型
s.isEmpty();//判空,boolean,空格是特殊的字符,不为空
构建字符串(StringBuilder)
是一个类,在底层用数组的形式存储字符串,防止一遍遍的拼接字符串效率低
自带方法
append:加入
length:求长度
reverse:反转
insert(位置,字符串):插入
StringBuilder s = new StringBuilder();
for(int i = 0;i<100;i++)
{
s.append(i);
}
System.out.println(s.toString());
包装类
Byte 、 Short、Integer、Long、Float、Double、Character、Boolean
基本类型与包装类型互转
int i = 10;
Integer i1;
i1=i;
int i2 = i1.intValue();//包装向普通转
//可自动拆箱
i2 = i1; 也对
回顾基本数据类型
byte short int long float double char boolean
日期类
* y(Y) 年->yyyy Y表示一年有52周,大于52周的转到下一年
* m(M) MM:月份 mm:表示分钟
* d(D) dd:一个月中的日期 D:一年中的日期
* h(H) hh:12进制 HH:24进制
* s(S) ss:秒 SSS:毫秒
//Date :日期类
//Calendar:日历类
输出从1970年1月1日到现在的时间戳:毫秒数
System.currentTimeMillis()
Date date = new Date();
// Java日期格式化:
/*
* y(Y) 年->yyyy Y表示一年有52周,大于52周的转到下一年
* m(M) MM:月份 mm:表示分钟
* d(D) dd:一个月中的日期 D:一年中的日期
* h(H) hh:12进制 HH:24进制
* s(S) ss:秒 SSS:毫秒
*
* */
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String dateFormatString = dateFormat.format(date); //日期转字符串
System.out.println(dateFormatString);
JDBC
预编译PreparedStatement
PreparedStatement 类继承自 Statement 类,在 JDBC 开发中用来取代前者。有以下两个优势:
- 可对 SQL 语句进行预编译,可以灵活地修改 SQL 语句,提高开发效率。
- 把用户输入单引号转义,防止恶意注入,保护数据库安全。
Connection connection = DriverManager.getConnection();
String sql = "INSERT INTO test(id,name) VALUES (?,?)";
PreparedStatement stmt = connection.preparedStatement(sql); // 创建对象并预编译
stmt.setInt(1, 755); // 在第一个占位符(?)位置插入数字
stmt.setString(2, "MrJoker"); // 在第二个占位符(?)位置插入字符串
stmt.executeUpdate(); // 更新并执行
批处理executeBath
PreparedStatement 类可以通过 executeBath 方法批量处理 SQL 语句,进一步提高效率。其返回值为一个 int[] 数组。
Connection connection = DriverManager.getConnection();
String sql = "INSERT INTO test(id,name) VALUES (?,?)";
PreparedStatement stmt = connection.prepareStatement(sql);
for (int i = 1; i <= 1000; i++) {
stmt.setInt(1, i);
stmt.setString(2, (i + "号士兵"));
stmt.addBatch(); // 语句添加到批处理序列中
}
preparedStatement.executeBatch(); // 语句发送给数据库批量处理
preparedStatement.clearBatch(); // 清空批处理序列
返回查询结果ResultSet
ResultSet rs = stmt.executeQuery(sql); // 获取返回结果
while(rs.next()){ // 输出返回结果
System.out.println(rs.getString("area_id"));
}
反射
相关API
java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造器 … …
异常处理
捕获异常catch
当方法执行抛出异常时,必须由专门的代码块对异常进行处理。
- try 语句:可能出现异常的代码块。
- catch 语句:捕获相应异常后停止执行 try 代码,转而执行对应 catch 代码。如果没有异常 catch 代码不会执行。
- finally 语句:无论是否发生异常,finally 代码总会被执行。一般用于释放资源。
注意事项
-
如果 try 语句中出现的异常未被 catch,默认将异常 throw 给上层调用者处理。但必须在方法中声明 throws。
-
try/catch 代码中的 return 语句会在执行完 finally 后再返回,但 finally 中对返回变量的改变不会影响最终的返回结果。
-
finally 代码中应避免含有 return 语句或抛出异常,否则只会执行 finally 中的 return 语句,且不会向上级抛出异常。
Java 7 后在 try 语句中打开 IO 流,会在跳出后自动关闭流。不必再用 finally 语句关闭。
class TestException{
public void writeList(int size) {
PrintWriter out = null;
try {
if(size < 1) throw new IndexOutOfBoundsException("至少要输出1个字符");
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < size; i++)
System.out.println("Value at: " + i + " = " + list.get(i));
} catch (IndexOutOfBoundsException e) {
System.err.println("Caught IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally {
if (out != null) out.close();
}
}
}
容器
基本接口
List接口
【列表】元素有序,可以按照索引进行操作 获取时下标从0开始
在相同索引位置进行add操作,则该位置的索引会顺势后移,并不会替换该位置元素即索引号与位置并非一一对应。
// 修改
list.add("data1"); // 末尾添加元素
list.add(0, "data0"); // 插入元素
list.remove(0); // 按索引删除元素(int)
list.remove("data"); // 按内容删除对象元素(Object)
list.remove(new Integer(3)); // 按内容删除基础类型元素
list.clear(); // 清除所有元素
list.set(0, "data2"); // 修改元素
// 查找
list.isEmpty(); // 判定是否为空
list.size(); // 查询列表元素个数
list.contains("data3"); // 判定是否含有元素
list.get(1); // 按索引查找元素
list.indexOf("data1"); // 查询索引号:如果有返回第一个,没有返回-1
list.lastIndexOf("data1"); // 查询索引号:如果有返回最后一个,没有返回-1
// 转化
list.toString(); // 转化为字符串
list.toArray(); // 转化为 Object[] 数组
(String [])list.toArray(); // 转化为对象数组,但不能是基础类型
Set接口
【集】数据不可重复。
// 修改
set.add("data"); // 添加元素
set.remove("data"); // 删除元素
set.clear(); // 清除所有元素
// 查询
set.get(1); // 按序号查找元素(仅限于有序的 set 接口)
set.isEmpty(); // 判断是否为空
set.size(); // 返回元素个数
set.contains("data"); // 判定是否含有元素Copy to clipboardErrorCopied
HashSet 类无序,因此不支持 get 方法:获取对象必须要通过 Iterator 来遍历。
Set 子类
- HashSet 类:【散列集】基于 HashMap 类实现。
- LinkedHashSet 类:【链式散列集】基于 LinkedHashMap 类实现。
- TreeSet 类:【树集】基于 TreeMap 类实现。
Collections类(帮助类)
Collections 类是针对集合类的一个帮助类,他提供一系列静态方法实现各种集合操作。
- 排序操作(主要针对List接口)
Collections.swap(list, 1, 2); // 元素交换顺序
Collections.shuffle(list); // 元素随机排序
Collections.reverse(list); // 元素颠倒排序
Collections.sort(list); // 元素按大小排序,可以自定义比较顺序
Collections.rotate(list, 2); // 元素右移指定长度
- 查找和替换
Collections.binarySearch(list, "data"); // 二分查找元素索引,只适用于有序集合
Collections.max(list); // 返回最大元素,可以自定义比较顺序
Collections.min(list); // 返回最小元素,可以自定义比较顺序
Collections.frequency(list, "data"); // 返回对象出现次数
Collections.fill(list, "data"); // 使用指定元素填充
Collections.replaceAll(list, "old", "new"); // 使用指定元素替换
- 上锁(主要针对List接口)
调用 Collections 类中的 synchronizedList 方法,可以将 List 接口转换成线程安全的容器使用。
List 接口中的方法都会被添加 synchronized 锁(效率不高)。但是 iterator 方法没有加锁,如果要遍历还需要在外层加锁。
List list = Collections.synchronizedList(new ArrayList());
synchronized (list) {
Iterator i = list.iterator();
while (i.hasNext())
foo(i.next());
}
线性存储
ArrayList类
【数组序列】实现了 List 接口,内部使用 Object 数组存储:
- 可以高效地按索引进行元素修改和查询。
- 添加元素时动态扩容:当容量满后,ArrayList 类会新建一个 1.5 倍容量的新数组,然后将当前数组数据全部复制过去。
ArrayList 构造方法
List<Integer> list = new ArrayList<>(); // 默认初始容量为 10
List<Integer> list = new ArrayList<>(100); // 自定义初始容量
List<Integer> list = new ArrayList<>(queue); // 构造时直接复制其他容器元素(可以是任何 Collection 类)
List list = new ArrayList(); // 未指定元素类型则为 Object 类
Hash存储
HashMap类
【哈希表】 实现 Map 接口。底层使用散列存储:构造一个 Entry 数组,根据 key 的 hash 值将 Entry 存入指定位置。
- key 值无序且不可重复,且允许 null 作为 key 值存在。
- 发生哈希冲突时,HashMap 采用链表保存多个元素。当链表长度大于 8 时,链表自动转化为红黑树。
- 达到负载因数后,HashMap 将调用 resize 方法动态扩容:新建一个 2 倍容量的新数组复制当前数组的数据。
HashMap 构造方法
注:Map<String,Integer>表示 key值为String类型,value为Integer类型
Map<String,Integer> map = new HashMap<>(); // 默认初始容量 16 负载因数 0.75
Map<String,Integer> map = new HashMap<>(32); // 自定义初始容量
Map<String,Integer> map = new HashMap<>(32, 0.5f); // 自定义初始容量和负载因数
Lambda表达式
语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。
//一个参数无返回
NoReturnOneParam noReturnOneParam = (int a) -> {
System.out.println("NoReturnOneParam param:" + a);
};
noReturnOneParam.method(6);
//一个参数有返回值
ReturnOneParam returnOneParam = (int a) -> {
System.out.println("ReturnOneParam param:" + a);
return 1;
};
int res2 = returnOneParam.method(6);
System.out.println("return:" + res2);
语法简化
import lambda.interfaces.*;
public class Test2 {
public static void main(String[] args) {
//1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
NoReturnMultiParam lamdba1 = (a, b) -> {
System.out.println("简化参数类型");
};
lamdba1.method(1, 2);
//2.简化参数小括号,如果只有一个参数则可以省略参数小括号
NoReturnOneParam lambda2 = a -> {
System.out.println("简化参数小括号");
};
lambda2.method(1);
//3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号
NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
lambda3.method();
//4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
ReturnOneParam lambda4 = a -> a+3;
System.out.println(lambda4.method(5));
ReturnMultiParam lambda5 = (a, b) -> a+b;
System.out.println(lambda5.method(1, 1));
}
}
lambda表达式引用方法
有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。
**语法:**方法归属者::方法名 其中静态方法的归属者为类名,普通方法归属者为对象
//lambda2 引用了已经实现的 doubleNum 方法 ,doubleNum为静态方法
ReturnOneParam lambda2 = Exe1::doubleNum;
System.out.println(lambda2.method(3));
Exe1 exe = new Exe1();
//创建exe对象是为了实现非静态方法
//lambda4 引用了已经实现的 addTwo 方法
ReturnOneParam lambda4 = exe::addTwo;
System.out.println(lambda4.method(2));
构造方法的引用
一般我们需要声明接口,该接口作为对象的生成器,
通过 类名::new 的方式来实例化对象,然后调用方法返回对象。
interface ItemCreatorBlankConstruct {
Item getItem();
}
interface ItemCreatorParamContruct {
Item getItem(int id, String name, double price);
}
public class Exe2 {
public static void main(String[] args) {
ItemCreatorBlankConstruct creator = () -> new Item();
Item item = creator.getItem();
ItemCreatorBlankConstruct creator2 = Item::new;
Item item2 = creator2.getItem();
ItemCreatorParamContruct creator3 = Item::new;
Item item3 = creator3.getItem(112, "鼠标", 135.99);
}
}
forEach用法
forEach的三种用法:
//1.直接forEach遍历
for(int i:list){ System.out.println(i); }
//2.用system.out::prinimport lambda.interfaces.*;
public class Test2 {
public static void main(String[] args) {
//1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
NoReturnMultiParam lamdba1 = (a, b) -> {
System.out.println("简化参数类型");
};
lamdba1.method(1, 2);
//2.简化参数小括号,如果只有一个参数则可以省略参数小括号
NoReturnOneParam lambda2 = a -> {
System.out.println("简化参数小括号");
};
lambda2.method(1);
//3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号
NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
lambda3.method();
//4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
ReturnOneParam lambda4 = a -> a+3;
System.out.println(lambda4.method(5));
ReturnMultiParam lambda5 = (a, b) -> a+b;
System.out.println(lambda5.method(1, 1));
}
}tln
list.forEach(System.out::println);
//3.有map集合 键值对的情况下
set.forEach((key) -> {
System.out.println(key + "\t"+map.get(key));
});
Stream流处理
Java Stream类
JDK 1.8 新增。将要处理的元素集合看作一种流,在管道的节点上进行处理。使代码更简洁易读。
集合接口有两个方法来生成流,数据类型将由 Collection 转化为 Stream 。
-
stream
方法:为集合创建串行流。 -
parallelStream
方法:为集合创建并行流。
- Stream 的遍历方式和结果与 Iterator 无差别(便于转化),其优势在于其原型链的设计使得它可以对遍历处理后的数据进行再处理。
- parallelStream 提供了流的并行处理,底层使用 Fork/Join 框架,简单理解就是多线程异步任务的一种实现。处理过程中会有多个线程处理元素,具体由 JDK 负责管理。不保证有序性。
- 串行流和并行流之间可以通过
parallel
和sequential
方法相互转化。
Stream<Integer> stream = list.stream(); // 声明作为流处理
ParellerStream<Integer> pStream = stream.parallel(); // 转化为并行流
流操作
流处理的每个操作阶段都会封装到一个 Sink 接口里,处理数据后再将数据传递给下游的 Sink。
Stream 上的所有操作分为两类:中间操作和结束操作。Stream 是延迟执行的,只有调用到结束操作,才触发整个流水线的执行。如果未定义结束操作,那么流处理什么也不会做。
// 获取空字符串的数量
int count = strings.parallelStream() // 声明作为流处理
.filter(string -> string.isEmpty()) // 中间操作,过滤空元素
.count(); // 结束操作,计数
中间操作
映射 map
map
方法用于映射每个元素到对应的结果,其实就是对结果进行转化。
// 获取对应的平方数
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());Copy to clipboardErrorCopied
过滤 filter
filter
方法用于通过设置的条件过滤出元素。
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();Copy to clipboardErrorCopied
筛选 limit/skip
limit
方法用于获取指定数量的流(前 n 个), skip
方法用于去除指定数量的流(前 n 个)。
// 筛选出 11-20 条数据
Random random = new Random();
random.ints().limit(20).skip(10).forEach(System.out::println);Copy to clipboardErrorCopied
排序 sorted
sorted
方法通过 Comparable 接口对流进行排序,也可以自定义。
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);Copy to clipboardErrorCopied
去重 distinct
distinct
方法通过流元素的 hashCode 和 equals 方法去除重复元素。
Random random = new Random();
random.ints().distinct().forEach(System.out::println);
I/O
序列化
对象持久化
在 Java 程序中所创建的对象都保存在内存中,一旦 JVM 停止运行,这些对象都将会消失。因此以下两种情况必须通过序列化实现:
- 需要把对象持久化保存在文件中,在 JVM 重启后能够继续使用。
- 通过网络传送对象信息,在多个 JVM 间共享对象。
Serializable接口
在类中声明实现 Serializable 接口,表示允许 Java 程序对这个类的对象序列化:JVM 会将对象的成员变量保存为一组字节,这些字节可以再被 JVM 组装成对象。对象序列化只保存的对象的成员变量,且不会关注类中的静态变量。
- transient 字段:默认序列化机制就会被忽略。
- private 字段:序列化后不会被保护,任何 JVM 都可读取。
//person类的读入读出
//对于 class Person implements Serializable
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file));
Person person = new Person("John", 101, Gender.MALE);
oout.writeObject(person);
oout.close();
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
Object newPerson = oin.readObject(); // 没有强制转换到Person类型
oin.close();
标准输入/输出
标准输入流system.in
读取标准输入设备数据(键盘),每次输入将以换行符结束。数据类型为 InputStream。
char c = (char)System.in.read(); // 读取单个输入字符,返回其 ASCII 值(int)
byte[] b = new byte[20];
System.in.read(b); // 读取输入定长字符组,返回字符个数(int)
标准输出流system.out
向标准输出设备输出数据(控制台)。数据类型为 PrintStream。
System.out.print("hello"); // 输出数据
System.out.println("hello"); // 输出数据并换行
格式化输出
通过 printf 方法可以输出指定格式数据:其中 %d
表示整型数字, %f
表示浮点型数字, %%
表示百分号。
在百分号后加入特殊符号,可以指定数据的显示类型。
符号 | 作用 | 示例 | 效果 |
---|---|---|---|
+ | 为正数或者负数添加符号 | (“%+d”,99) | +99 |
2 | 位数(默认右对齐) | (“%4d”, 99) | __99 |
− | 左对齐 | (“%-4d”, 99) | 99__ |
0 | 数字前补0 | (“%04d”, 9999) | 0099 |
, | 以“,”对数字分组 | (“%,d”, 9999) | 9,999 |
.2 | 小数点后精确位数 | (“%5.2f”, 9.999) | _9.99 |
字节流
InputStream/OutputStream 类
以字节为单位进行读取的数据流。常用来处理二进制数据的输入输出,如键盘输入、网络通信。但字节流不能正确显示 Unicode 字符。
输入流
InputStream in = new InputStream(socket.getIntputStream()); // 创建输入对象
int len = in.available(); // 读取输入对象长度
char c = (char)in.read(); // 读取输入字节
byte[] b = new byte[len]; // 连续读取输入字节
in.read(b);
in.close(); // 关闭输入对象Copy to clipboardErrorCopied
输出流
OutputStream out = new OutputStream(socket.getOutputStream()); // 创建输出对象
byte[] b = {1,2,3}; // 导入输出字节
out.write(b);
out.flush(); // 刷新输出对象,输出字节
out.close(); // 关闭输出对象,输出字节
字符流
Reader/Writer 类
以字符为单位进行读取的数据流。只能用于处理文本数据。且所有文本数据,即经过 Unicode 编码的数据都必须以字符流的形式呈现。
我们在 Java 程序中处理数据往往需要用到字符流,但在通信中却需要使用字节流。这就需要进行数据格式转化。
InputStreamReader 类
Reader 类子类。将字节流数据转换成字符流,常用于读取控制台输入或读取网络通信。可指定编码方式,否则使用 IDE 默认编码方式。
// 读取键盘输入
InputStreamReader in = new InputStreamReader(System.in);
// 读取套接字通信,并指定编码格式
InputStreamReader in = new InputStreamReader(socket.getInputStream(), "UTF-8");Copy to clipboardErrorCopied
OutputStreamWriter 类
Writer 类子类。将字符流数据转换成字节流,常用于发送网络通信。
// 数据转化为字节流发送
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());Copy to clipboardErrorCopied
文件流
File 类
用于文件或者目录的描述信息,默认加载当前目录。
File f1 = new File("FileTest.txt"); // 读取当前目录文件
File f2 = new File("D://file//FileTest.txt"); // 读取指定目录文件Copy to clipboardErrorCopied
FileInputStream/FileReader 类
FileInputStream 类读取字节流文件信息,FileReader 类读取字符流文件信息。
public class TestFileReader {
public static void ReadFile(String textName) {
int c = 0;
try {
// 连接文件
FileReader fr = new FileReader("D:\\Workspaces" + textName);
// 执行操作
while ((c = fr.read()) != -1) {
System.out.print((char)c);
}
fr.close();
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
} catch (IOException e) {
System.out.println("文件读取错误");
}
}
}Copy to clipboardErrorCopied
FileOutputStream/FileWriter 类
FileOutputStream 写入字节流文件信息,FileWriter 类写入字符流文件信息。
public class TestFileWriter {
public static void ReadFile(String textName) {
int c = 0;
try {
// 追加模式,写入文本信息会添加到文本尾部
FileWriter fw = new FileWriter(textName);
// 覆盖模式,写入文本信息会覆盖原有数据
FileWriter fw2 = new FileWriter("data.txt", false);
// 执行操作
fw.write("Hello world!欢迎来到 java 世界\n");
fw.append("我是下一行");
fw.flush();
System.out.println("文件编码为" + fw.getEncoding());
fw.close();
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
} catch (IOException e) {
System.out.println("文件写入错误");
}
}
}Copy to clipboardErrorCopied
缓冲流
BufferedInputStream/BufferedReader 类
BufferedInputStream 类将输入字节数据暂存到缓冲区数组,BufferedReader 类将输入字符流数据暂存到缓冲区数组。
JVM 在缓冲区数组满后一次性获取缓冲区内的数据,减少了对 CPU 的频繁请求。
BufferedOutputStream/BufferedWriter 类
BufferedOutputStream 类将输出字节数据暂存到缓冲区数组,BufferedWriter 类将输出字符流数据暂存到缓冲区数组。文章来源:https://www.toymoban.com/news/detail-432979.html
JVM 在刷新时一次性将缓冲区内的数据输出到外部设备,减少了对 CPU 的频繁请求。文章来源地址https://www.toymoban.com/news/detail-432979.html
class TestBuffer{
public static void bufferUse() throws IOException {
// 通过缓冲区读取键盘输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 通过缓冲区输出到文件
BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"));
// 执行操作
String line = null;
while((line = br.readLine()) != null){ // readLine 缓冲流特有方法,一次性读取一行
if("over".equals(line)){
break;
}
bw.write(line);
bw.newLine(); // newLine 缓冲流特有方法,写入换行符
bw.flush();
}
bw.close();
br.close();
}
}
到了这里,关于Java基础整理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!