微信公众号:《极客小祥》
永远相信美好的事情即将发生
环境变量配置
JAVA_HOME:配置的是jdk的根目录
path:配置bin目录(%JAVA_HOME%\bin)
基本格式
类名必须和文件名保持一致
public class 类名{
// 类名每个单词首字母大写
public static void main(String[] args) {
}
}
1、java工具包
jdk:java开发工具包(java development kit),代码编写依赖jdk
jre:java运行环境(java runtime environment),提供javav程序运行的环境
jvm:java虚拟机(java virtual machine),确切说程序是在jvm里面运行的(只认识class字节码文件)
2、常用cmd命令
dir:显示当前路径下的目录
cd:路径操作
cls:清除当前屏幕
javadoc 程序名.java:生成Doc文档
3、cmd运行步骤
先写程序
编译:javac 程序名.java
执行:java 程序名
4、注释
单行注释://注释内容 快捷键:Ctrl+/
多行注释:/*注释类容*/ 快捷键:Ctrl+Shift+/
文档注释:/**注释内容*/(对类和文档进行解释)
/*
多行注释 一般写在类的开头
写出
1. 类的功能
2. 类的实现步骤
*/
public class name{
// main是程序的主方法 固定格式 程序的入口
public static void main(String[] args) {
System.out.println("HelloWorld");
}
}
目录文件夹
src文件夹:源文件夹 里面存放(包package)java文件
bin文件夹:存放编译之后的(包package)class文件
Class–>Package规范:公司域名后缀名+公司名称+其他
com/cn/edu.java.other
设置相关
字体大小调节:Window->Preferences->Appearance->Colors and Fonts->Basic->Text Font
设置统一编码格式为UTF-8:Window->Preferences->workspace->Text file encoding
设置注释格式:windows–>preference–>Java–>Code Style–>Code Templates–>code–>new Java files
变量的定义和注意事项
变量定义后,不赋值不能使用
变量有自己的作用范围,变量的有效范围定义在一对大括号内
变量不允许重复定义
数据类型
1、基本数据类型(四类八种)
Java默认数据类型是int
整数默认类型是int,小数默认类型是double
整数:byte/short/int/long
byte:1个字节 -128~127
short:2个字节
int(默认):4个字节
long:8个字节(过大的数后面加上L)
小数:float/double(默认)
float:4个字节
double:8个字节
布尔:boolean(默认false)
boolean:1个字节
单个字符:char(默认是’’)
char:2个字节
2、引用数据类型
String:字符串类(默认是null)
String + 基本类型:字面量数据类型
数组:数据类型[] 数组变量名 = new 数据类型[长度]
任意引用数据类型都存在堆里面
3、数据类型转换
自动类型转换:**范围小(byte)的可以直接转换为范围大(int)**的
byte -> short -> int -> long -> float -> double
public class DateVonvert {
public static void main(String[] args) {
double b = 1000; // 出现了类型的自动转换,int自动转换为double
System.out.println(b);
byte b = 111;
int j = b; // byte转换为int
System.out.println(j);
}
}
强制类型转换:被转后的数据类型 变量名 = (被转后的数据类型)要被转的数据
public class DateVonvert {
public static void main(String[] args) {
double dd = 3.14;
// 被转后的数据类型 变量名 = (被转后的数据类型)要被转的数据
int ii = (int) dd;
System.out.println(ii);
byte bb = (byte) 200;
System.out.println(bb); // 丢数据
}
}
运算符
1、算术运算符
+ 加法,连接
- 减法
* 乘法
/ 除法
**%**取模,取余数
++ 自增1
– 自减1
public class Operator {
public static void main(String[] args) {
// + 连接作用,将一个字符串和其他数据连接起来
// + 任何类型只要和字符串+,所有的数据都变成了字符串
// + 遇到字符串,变成连接符号"5+5=55"
System.out.println("5+5="+5+5);
// ++ 写在变量前面和后面的区别
int i = 5;
int j = i++;
// j = i++ ++后算,先把i赋值给j,i自己再++
System.out.println(i); // 6
System.out.println(j); // 5
int m = 5;
int n = ++m;
// n = ++m ++先算,再把m++赋值给n
System.out.println(m); // 6
System.out.println(n); // 6
}
}
2、赋值运算符
= / += / -= / /= / %=
public class Operator {
public static void main(String[] args) {
byte b = 1;
b = (byte)(b + 1); // 必须转换 不然报错
System.out.println(b);
byte b1 = 1;
b1 += 1; // 等同于(byte)(b + 1)
System.out.println(b);
}
}
3、比较运算符
== / != / < / > / <= / >=
结果只有 true 或者 false
比较字符串是否一致:名称1.equals(名称2)
4、逻辑运算符
对两个boolean类型数据之间进行计算结果也是boolean类型
& 与:一个false,结果就是false
| 或:一个true,结果就是true
^ 异或:两边相同为false,不相同为true
! 取反:!true为false !false为true
&& 短路与:一边是false,另一边不运行
|| 短路或:一边是true,另一边不运行
5、三元运算符
公式:布尔表达式?结果1:结果2
结果1和结果2数据类型保持一致
布尔表达式是true,三元运算符结果就是–>结果1
布尔表达式是false,三元运算符结果就是–>结果2
public class Operator {
public static void main(String[] args) {
System.out.println(3>2?99:88); // 99
System.out.println(3>5?99:88); // 88
}
}
循环控制语句
1、If Else
if(表达式){
//表达式成立执行这里面的语句
//语句
}else if(表达式2){
}else{
//不满足执行这里的语句
}
2、While/Do While
两者区别:
while 先判断是否满足条件 满足就执行循环体
do while 无论满不满足循环体都先执行一次
while(判断条件){
// 成立执行这里的语句
}
do{
//执行一次
}while(判断条件);
3、Switch Case
// switch后表达式满足的数据类型有
// int byte char String(1.7版本) enum(枚举) short
switch(表达式){
// case后的数据类型要和switch表达式的数据类型保持一致
case 表达式1:
代码逻辑;
break;
case 表达式2:
代码逻辑;
break;
case 表达式n:
代码逻辑;
break;
// 前面所有的表达式都不满足执行default语句后的代码
default:
代码逻辑;
break;
}
4、For
for(表达式1;表达式2;表达式3){
// 代码逻辑
}
// 增强for循环
for(数组元素数据类型 变量名称:数组变量名){
// 循环体
}
5、Break,Continue,Return
Break:直接终止整个循环体,不能单独使用在if里
Continue:结束本次循环体,开始下个循环
Return:结束整个方法
6、Scanner使用
Scanner input = new Scanner(System.in);,定义输入
int a = input.nextInt();,接收用户输入
input.close(),关闭流
7、断点调试
先双击行首数字出
F6程序往下走一步
F8走到下一个断点处
数组
1、一维数组
语法
- 数据类型[] 变量名 = new 数据类型[长度];
- 数据类型[] 变量名 = {值1,值2,值3,值n};
- 获取数组长度:数组名.length;
2、二维数组
语法
数据类型[][] 变量名 = 数据类型[m][n];
数据类型[][] 变量名 = 数据类型[m][];
数据类型[][] 变量名 = {{元素1},{元素2},{元素3}};
// 3表示二维数组的长度是3(存放3个一维数组)
// 4表示每个一维数组里面可以存放4个元素
String[][] strArr = new String[3][4];
System.out.println(strArr.length); // 打印二维数组的长度
System.out.println(strArr[0].length); // 打印一维数组长度
3、Arrays工具类
Arrays.toString(arr); // 将数组内容转成字符串输出
Arrays.sort(arr); // 默认从小到大排序
Arrays.copyof(源数组,新数组长度); // 拷贝数组
Arrays.equals(数组1,数组2); // 判断两个数组是否一致
Arrays.binarySearch(数组名, 要查找的元素); // 查找元素在数组中的索引,找不到返回(-插入点-1),数组必须有序才能查找
排序(Sort)
1、冒泡排序
效率最慢
int[] arr = {23,2,44,1};
// 控制排序的轮数
for(int i = 0; i<arr.length-1; i++) {
// 控制元素与相邻元素相比
for (int j = 0; j < arr.length-1-i; j++) {
// 判断两个相邻的元素
if(arr[j]>arr[j+1]) { // arr[j]位置交换
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
2、选择排序
for(int i = 0; i<arr.length-1; i++) {
int min = arr[i]; // 定义一个最小值
int minindex = i; // 获得最小值的索引
// 判断遍历数组出最小值
for (int j = i+1; j < arr.length; j++) {
if (min>arr[j]) {
min = arr[j];
minindex = j;
}
}
// 交换位置
int temp2 = arr[i];
arr[i] = arr[minindex];
arr[minindex] = temp2;
}
3、插入排序
效率最快
for (int i = 1; i < arr.length; i++) {
int temp = arr[i]; // 数组的第二位
int leftindex = i-1; // 左侧索引
// arr[leftindex] 后移
while (leftindex >= 0 && arr[leftindex] > temp) {
arr[leftindex + 1] = arr[leftindex];
leftindex--;
}
// 空位
arr[leftindex + 1] = temp;
}
类和对象
1、类的创建
public class 类名{
// static表示静态的
// 下面都是类的属性
static String name; // 姓名
static String gender; //性别
static int age;
}
2、类的方法
- 权限修饰符:public static(公共的),protected(受保护的),private(私有的),默认(default)
- 方法返回值:数据类型,void(无返回值数据类型)
- 方法名():规范:首字母小写,第二个单词字母大写,名字不能重复
- 方法的参数:形式参数,形参 所有数据类型都可以充当形参
//1.无参无返回值
public static void method1() {
System.out.println("无参无返回值");
}
//2.无参有返回值:必须加return语句,返回要返回的数据(数据类型必须是返回值的数据类型)
public static String method2() {
System.out.println("无参有返回值");
String str = "hello";
return str; // 结束当前方法
}
//3.有参无返回值(参数的个数>=1)
public static void method3(int[] arr,int num,int...obj) {
System.out.println("有参无返回值");
System.out.println(arr);
}
//4.有参有返回值
public static int method4(String str,int i) {
System.out.println("有参有返回值");
return i; // 必须返回和参数相同的数据类型
}
可变参数:数据类型…参数名字,可变参数本质上是一个数组
可变参数注意事项:
- 一个方法中,可变参数只能有一个
- 可变参数必须写在参数列表的最后一位
3、创建对象
语法:类名 对象名 = new 类名();
Person zhangSan = new Person();
System.out.println(zhangSan); // 输出内存地址
调用类的属性和方法
zhangSan.name = "张三";
zhangSan.gender = "男";
zhangSan.age = 20;
System.out.println(zhangSan.name); // 输出name
4、调用方法
语法:方法名();
public static void method1() {
System.out.println("无参无返回值");
}
method1() // 调用method1方法
5、方法重载
- 方法名相同
- 参数数据类型,参数顺序不一样
- 不考虑返回值和权限修饰符
public Animal() {
// 初始化一些变量数据
}
// 构造方法重载
public Animal(String name1) {
name = name1;
}
6、成员变量和局部变量
- 存在位置不一样:成员变量在类里面,局部变量在方法里面
- 作用范围不一样:成员变量在类里任何地方都可以访问,局部变量只可以在方法里面使用
- 内存储存位置不一样:成员变量在堆里,局部变量在栈里
- 初始值不一样:成员变量有初始值,不需要初始化,局部变量没有初始值,必须初始化
枚举类
- 定义语法:
public enum Test(){
'这是枚举类'
}
- 注意:
- 枚举类必须先定义对象(实例),再定义成员变量和成员方法
public enum Test(){ '对象(实例),多个对象中间用逗号隔开' MONDAY, '默认基于无参构造创建的对象' TUESDAY, WEDNESDAT, THURSDAY("周四"); '使用有参构造创建对象' '想获得对象中的参数值,通过调用对象的get方法获得' '成员变量' private String name; public Integer id; '枚举类中的所有构造方法都必须是私有的' private Week(){} private Week(String name){} }
- 枚举类中的对象值一般不允许修改,所以一般只给get方法
面向对象三大特性
1、封装
对私有属性提供对外的公开访问方法:使用**setter()和getter()**方法
private int age; // 年龄赋值的时候 要进行判断 private修饰成员只能在本类中调用
String tname;
public void setAge(int age1) {
if (age1 < 22) {
System.out.println("年龄不合法!");
System.out.println("年龄默认设置为22岁!");
age1 = 22;
}
age = age1;
}
public int getAge() {
return age;
}
lombok使用教程
this关键字
- 当成员变量与局部变量重名的时候,可以使用this来辨别,this指代的是当前对象
- this充当实参
- this可以调用构造函数this(),必须在代码的第一行
- this可以访问属性
- this不能在static所修饰的方法中运用
static关键字
- 静态方法里面不能访问非静态成员
- 如果是static修饰的成员变量,最好初始化
- 静态方法中不能使用this
- 可以和任何权限修饰符一起使用:public/private/protected/final
- 数据是让所有对象共享的
静态代码块:
static {
初始化数据,不管创不创建对象都走
只运行一次
System.out.println("静态代码块");
}
{
只有在创建对象的时候才会走这句话
System.out.println("普通代码块");
}
2、继承(extends)
语法:public class 类1 extends 类2{},一个类只能继承一个类
子类对象创建时会默认先执行父类的无参构造
super
- 访问父类构造方法(super())
- 访问父类的成员变量和成员方法(super.父类变量名/方法名)
方法重写(override)
前提条件:必须要有层级关系
- 方法重写出现在子类里面
- 方法名,形式参数必须和父类保持一致
- 子类访问权限修饰符 >= 父类的
- 子类返回值类型 <= 父类的
- 重写父类方法前面加上:@Override
权限修饰符
- public:可以修饰类和成员变量,在整个项目中都是友好的
- protected:可以修饰成员变量,在整个包内和子类中友好
- 默认不写:可以修饰类和成员变量,在包内友好
- private:可以修饰成员变量,在本类中友好
- final:可以修饰常量,被修饰的方法中不能被重写,在继承中不被继承
3、多态
发生多态条件:
- 父类对象指向任何一个子类的实例(对象)
- 编译时数据类型(=左边)与运行时数据类型(=右边)不一致时
- 子类对象转成父类实例向上转型
- 创建对象发生多态:父类对象 名称 = new 子类对象();
- 父类对象转成子类实例(强制转换),向下转型,要配合instanceof一起使用
- 访问成员变量看**=左边的数据,访问成员方法看=右边**
弊端:无法访问子类特有的成员(变量、方法)
instanceof
使用:父类实例 instanceof 子类对象
抽象类和接口
1、抽象类
使用条件:当所有子类都需要重新父类的逻辑时,父类方法体就变得没有意义,就把父类方法声明成抽象的方法
使用方法:访问权限修饰符 abstract 返回值类型 方法名();
注意:抽象类不能创建对象,体现在多态上,抽象类的构造方法主要是满足子类对象的创建
2、接口(interface)
创建接口
public interface 接口名{
}
项目命名规范
- ****Dao/DAO.java,UserDao.java
- ****Service.java,UserService.java
接口中的内容
常量必须为public static final修饰,常量名字必须都是大写
抽象方法必须为publice abstract修饰
JDK1.8之后有普通方法,但必须使用default static修饰
访问父类的普通方法使用super.方法名()
接口的作用
- 接口可以通过implements实现多调用,一个类可以实现多个接口
- 主要用于多态的使用
- 接口和接口之间可以实现多继承
3、接口和抽象类的区别
共同点:都不能实例化,都用于多态
不同点:接口只有常量和抽象方法和default/static所修饰的功能方法,抽象类有成员变量,成员方法,抽象方法,构造方法,静态代码块
异常
异常Exception(类) —> 可以处理
错误Error(类) —> JVM抛出,程序直接终止
它们有共同的父类:Throwable
异常可以分为两大类:
- 可检测到的异常checkedException:PasreException,SQLException,ClassNotFoundException,IOException
- 运行时的异常RuntimeException:NPE,ClassCastException
1、捕获异常的方法
String getMessage():获得详细的异常信息字符串内容
void printStackTrace():将详细异常信息通过流打印(输出)至控制台
出现多个异常的情况下,只走其中一个异常,就是说catch只走一次!
try{
可能会出现异常的代码
}catch(异常类 变量名 ){ 捕获具体的异常类的
//处理异常信息
//避免捕获不处理异常信息
1.后端开发(服务器端开发)--->java项目运行在Linux服务器
异常日志记录异常信息(将异常信息写入异常日志文件) slf4j log4j
2.异常信息传递 (throw) 将异常信息从底层到顶层全部输出。
将当前异常类对象 封装到 级别高的异常对象里面
3.异常工具类返回的错误信息
return ServerResponse.error("msg","code");
}catch(异常类 变量名 ){
处理异常信息的方式
System.out.println(exception.getMessage());
exception.printStackTrace();
}
finally{
释放资源
不管是否有异常出现 都会执行的
}
2、抛出异常 throws
throw 声明抛出一个具体的异常对象
- 异常信息传递 (throw)
- 结束程序
- 与自定义异常结合使用
public static void a() throws ArithmeticException{
将异常类抛出给上级(调用者);
System.out.println("异常之前");
}
public static int calMoney(String boorowTime, String returnTime)
if(boorowTime == null || returnTime == null){
抛出一个异常信息
throw new NullPointerException("参数数据不能为null")
遇见throw程序直接结束
}
将String时间数据转换为Data
String pattren = "yyyy-MM-dd HH-mm-ss"; // 创建一个格式
SimpleDataFormat dateFormat = new SimpleDataFormat(pattren);
// 格式化数据(解析) 将字符串解析为data类型的数据
// 有一个可检测的异常
try{
Data borrowData = dateFormat.parse(boorowTime);
Data returnData = dateFormat.parse(returnTime);
// 计算两个日期的间隔
// 将Date类型的数据转换成数值型的数据
long borrow = borrowData.gettimr(); // data代表的是时间的毫秒数
long return1 = returnData.gettimr();
int hour = (int)((return1 - borrow)/1000/3600); // 转换成int类型的时间
} catch(ParseException e){
e.printStackTrace();
}
lang包常用类
1、Integer
包装类分为四类八种
Byte,Shory,Integer,Long,Float,Double,Character,Boolean
成员变量的数据类型使用包装类
Integer介绍:
- final所修饰的类
- 继承于Number
- 实现了一个**Comparable<Integer>**接口
- 赋值只能给数字类型和数字类型的字符串
基本类型的数据转换成了一个包装类 —> 自动装箱操作
// 底层实现:Integer num = Integer.valueOf(100);
Integer num = 100;
包装类的对象转换成基本类型的数据 —> 自动拆箱操作
// 底层实现:int num1 = num.intValue();
int num1 = num;
Integer num2 = new Integer(100);
Integer num3 = new Integer("100");
int num4 = 100;
Integer num5 = 100;
Integer num6 = 100;
Integer num7 = 200;
int num8 = 200;
System.out.println(num2=num2); false
这里实现了包装类的拆箱操作
System.out.println(num2=num4); true
System.out.println(num4=num5); true
System.out.println(num1=num4); false
整数缓存池:数组 Short[] Integer[] Long[],范围在-128~127之间,
两个数比较在这之间为True,否则为False
Integer num5 = 100;
Integer num6 = 100;
Integer num7 = 200;
int num8 = 200;
System.out.println(num5=num6); true
System.out.println(num7=num8); false
Integer功能方法
比较数据类型是否一致
//equals方法从Object继承 是Integer重写父类的euqals
System.out.println(num1.equals(num2));
//返回值只有0 -1 1
System.out.println(Integer.compare(num1, num2));
//从Comparable实现过来的
System.out.println(num1.compareTo(num2));
// Objectes JDK1.7后有的
System.out.println(Objects.equals(num1, num2));
String 和 Integer转换
String strNum = "100";
int num = new Integer(strNum); //第一个方法
Integer num2 = Integer.valueOf(strNum); //第二个方法
Integer num3 = Integer.parseInt(strNum); //第三个方法
Integer num4 = Integer.parseInt(strNum,2); //2代表进制数,输出结果都是10进制为主
Integer 转换成 String
Integer in = 100;
String str = in.toString(); // 转换成字符串
int i = 10;
String j = i + ""; // int转换为String
2、Character
Character功能方法
将字符串转换为指定进制
System.out.println(Character.MAX_RADIX); //最大进制 36
System.out.println(Character.MIN_RADIX); //最小进制 2
String str = "110";
char[] chs = str.toCharArray();
// 将第一位转换为10进制的数
System.out.println(Character.digi(chs[0], 10));
Character ch1 = '我';
if(Character.isLetter(ch1)){
判断是否为大小写字母
Character.toLowerCase(ch1); //小写
Character.toUpperCase(ch1); // 大写
}else if(Character.is.Digit(ch1)){
判断是否为数字
}else if(Character.isWhitesace(' ')){
判断是否为空字符串
}
3、Math
获得随机数
Math.random(); // 范围是0.0-1.0 包头不包尾
求几次幂
Math.pow(2,2); // 求2的2次幂
四舍五入
Math.round(4.6); // 结果是5
求一个数的平方根
Math.sqrt(4.0); // 结果是2.0
最大值最小值
Math.max(10,1)
Math.min(10,1)
获取绝对值
Math.abs(-10); // 变成10
4、Object(基类/超类)
获得对象的哈希码值(返回值是int)
hashCode()
获得一个对象(类/接口字节码文件)
getClass();
判断元素是否为空
Objects.requireNonNull(元素名);
在另外一个线程里面唤醒另外一个正在wait的线程
notify();
notifyAll();
线程等待
wait();
wait(long timeout);
wait(long timeout, int nanos);
创建(克隆)对象,获得一个对象的副本
clone();
浅克隆: 对于包装类,String-->克隆的是数据
其它引用类型-->克隆的是地址
深克隆:其它引用类型-->重新开辟内存
5、Class
表示正在运行的类或者接口(获得正在运行的类或者接口的class文件)
反射最基本的一个类–>获得类/接口的所有内容
一般用于底层的封装和框架的开源
获得Class类的对象的方式
1、创建一个Class类的实例
Person person = new Person();
Class clazz = person.getClass(); // clazz就是Person类的字节码文件
clazz.getName(); // 获得类或者接口的全限定名称--->包名+类名
clazz.getSimpleName(); // 拿到类名
2、创建一个Class类的实例
Class clazz = Person.class; // clazz就是Person类的字节码文件
3、创建一个Class类的实例
try{
Class.forName("给类或者接口的全限定名称");
Object obj = clazz.newInstance(); // 创建对象 默认执行无参构造
}catch(ClassNotFoundException e){
e.printStackTrace();
}
返回到类的类加载器(bin目录)
clazz.getClassLoader();
查找具有给定名称的资源
clazz.getResourceAsStream("资源文件路径");
获得类的属性 对属性赋值(Field类)
Field[] fields = clazz.getFields(); // 只能获得public所修饰的属性
fields = clazz.getDeclaredFields(); // 获得类的所有属性
6、String
实现了java.io.Serializable, Comparable<String>, CharSequence接口
创建字符串
构造
String str1 = new String();
String str2 = new String("hello");
byte[] bytes = {78,98,99}
String str3 = new String(bytes); //将字节数组转为字符串内容
获得字符串的字节内容
注意编码和解码格式统一
//使用默认的编码格式解析成字节数组
System.out.println("哈哈哈哈".getBytes());
// 将字节数组使用指定的格式进行编码处理
System.out.println("哈哈哈哈".getBytes("GBK").length);
// 将字节数组使用指定的编码格式进行解码处理
System.out.println("哈哈哈哈".getBytes(),"UTF-8");
Charset代表具体的编码格式
// 查看当前工作空间默认编码格式
System.out.println(Charset.defaultCharset());
将字符数组转换为字符串内容
char[] ch = {23,'a','家','好'};
String str4 = new String(ch);
toCharArray字符数组转换为字符串内容操作
String str4 = new String("啊啊啊啊".toCharArray());
String功能方法
获得字符串指定索引的字符内容(返回值是char类型)
str.charAt(1); // 不能超过字符串的总长度
字符串之间的比较(返回值是int类型)
str.compareTo("abc"); //ASII码值相减
str.compareToIgnoreCase("ABC"); // 不区分大小写进行比较
str.equals("abc"); // 返回值是boolean类型
str.equalsIgnoreCase("ABC"); // 不区分大小写进行比较,返回值是boolean类型
将指定的字符串内容追加到字符串的末尾(返回值是String类型)
str.concat("_123"); // abc_123,返回的是一个新的字符串内容,str不会发生改动
判断字符串中是否包含指定字符序列内容(返回值是boolean类型)
str.contains("a"); // 判断str中是否包含a
将任意类型的数据转换为字符串(返回值是String类型)
String.valueOf(1);
判断字符串中是否以某个类型开头和结尾(返回值是boolean类型)
str.endsWith("a"); // 判断是否是a结尾
str.startsWith("b"); // 判断是否是b开头
返回字符串的哈希吗值
str.hashCode();
获得指定字符串第一次出现的索引位置(返回值是int类型)
找不到指定的字符串内容返回值是-1
str.indexOf("a");
str.indexOf("a",1) // 从第二个元素开始查找
获得指定字符串最后一次出现的索引位置(返回值是int类型)
找不到指定的字符串内容返回值是-1
str.lastIndexOf("a");
str.lastIndexOf("a",1); // 从第一个开始查到最后一次出现的位置
获得当前字符串的副本(返回值是String类型)
str.intern(); //返回是一个常量池的数据(地址)
判断字符串是否是空(返回值是boolean类型)
str.isEmpty();
使用分隔符连接字符串内容(返回值是String类型)
String.join("_","a","b","c"); // a_b_c 后面可以写多个数据
判断字符串是否匹配正则的要求(返回值是boolean类型)
str.matches("abc"); // abc就是正则
使用指定字符串替换字符串内容(返回值是String类型)
str.replace('a','b'); // 将所有a替换成b
str.replace("a","abc"); // 将所有a替换成abc
str.replaceAll("支持正则", "abc"); // 可以支持正则表达式
str.replaceFirst("a","abc"); // 只替换第一个出现的a,支持正则
将字符串使用指定的正则表达式进行分割(返回值是String[]类型)
str.split("a"); // 通过a把字符串分隔开 支持正则
str.split("a",2) // 将字符串分为2个,通过a分割
截取部分字符串内容(返回值是String类型)
// 从第一个索引开始截取到第三个索引,包头不包尾
str.substring(1,3);
str.substring(str.indexOf("xxx"),str.lastIndexOf("xxx")); // 从第一次出现的字符串截取到最后一次出现字符串的位置
转换为大小写(返回值是String类型)
str.toUpperCase(); //转换为大写
str.toLowerCase(); //转换为小写
去掉字符串左右两边空格(返回值是String类型)
str.trim();
去掉中间空格
str.trim.replace(" ","");
str.trim.replaceAll(" ","");
7、StringBuffer/StringBuilder(字符串变量类)
StringBuffer:
值可以改变。线程安全(StringBuffer所有的方法都是同步的synchronized) 效率慢
StringBuilder:
值可以改变 线程不安全(不同步的),效率最快,(绝对不能作为成员变量进行使用)
StringBuffer功能方法
创建初始化对象
StringBuffer buffer = new StringBuffer("hello");
追加字符串
buffer.append("123"); // 始终是同一对象,不会浪费内存
buffer.insert(索引值,"追加的内容");
删除字符串
buffer.delete(开始索引, 结束索引); // 包头不包尾
buffer.deleteCharAt(删除指定索引位置); // 删除给出的索引位置的字符
反转字符串
buffer.reverse();
修改某个索引字符内容
buffer.setCharAt(索引位置,'要修改的内容');
StringBuilder功能方法
创建初始化对象
StringBuilder builder = new StringBuilder();
StringBuilder builder = new StringBuilder("hello");
String/StringBuffer/StringBuilder区别
- 从数据:
String: 数据不可变
StringBuffer/StringBuilder:值可以改变 - 从内容
String: 浪费内存
StringBuffer/StringBuilder;始终都是同一个对象 - 从线程安全
String/StringBuffer 线程安全(同步)
StringBuilder 线程不安全(不同步) - 效率
StringBuilder最快,其次是String,最后是StringBuffer
8、System
System类不能手动创建对象,因为构造方法被private修饰
方法:
获取系统当前毫秒值,可以测试程序执行时间
long start = System.currentTimeMillis();
for(int i = 0; i < 1000; i++){
}
long end = System.currentTimeMillis();
System.out.println(end - start); // 获取到执行for循环的时间
退出虚拟机,所有程序停止
System.exit(0);
收取对象的垃圾
System.gc();
获取当前系统的属性
System.getProperties();
复制数组
System.arraycopy(源数组,源数组的起始索引,目标数组,目标数组的起始索引,复制的个数);
util包常用类
1、Date
Date类对象用来表示时间和日期
该类提供一系列操纵日期和时间各组成部分的方法
构造方法重载
2、Calendar
Calendar类也是用来操作日期和时间的类,但它可以以整
数形式检索类似于年、月、日之类的信息
Calendar类是抽象类,无法实例化,要得到该类对象只能
通过调用getInstance方法来获得
3、Insatnt
JDK8的应用,推荐使用 Instant 代替 Date,LocalDateTime 代替 Calendar
4、LocalDate/LocalTime/LocalDateTime
LocalDate 获得当前系统的时间 2007-12-03
LocalTime 获得当前系统的时间 10:15:30
LocalDateTime 获得当前系统的时间 2007-12-03T10:15:30
此类也是不可变且线程安全
5、DateFormat
//时间转换成字符串
public static String formatDate(Date now,String pattern){
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
String result = sdf.format(now);
return result;
}
//字符串转换成时间
public static Date formateString(String str, String pattern){
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date date = sdf.parse(str);
return date;
}
数字的格式化
//#.## 保留两位小数
//#.##% 自动百分比计数并保留两位小数
//,### 每三位以逗号分隔
DecimalFormat df = new DecimalFormat("#.##");
String result = df.format(3.1415926);
6、Random(伪随机数类)
在多线程中是不安全的
创建实例
Random random = new Random();
Random random = new Random(10);
取一个随机整数值
random.nextInt(); // 随机生成整数
random.nextInt(10); //生成一个0-10的整数,包头不包尾
ThreadLocalRandom(随机数类)
在多线程中是安全的
ThreadLocalRandom localRandom =ThreadLocalRandom.current();
System.out.println(localRandom.nextInt(40, 100));//从40到99选一个随机数
7、加密解密
Base64
jdk1.8可正常使用
Base64.Encoder(加密),Base64.Decoder(解密)
该类使用RFC 4648和RFC 2045中规定的Base64编码方案来实现用于解码字节数据的解(编)码器。
'加密'
String pass = "1234";
Encoder encoder = Base64.getEncoder();// 获得编码器
String encodePass = encoder.encodeToString(pass.getBytes());
'解密'
Decoder decoder = Base64.getDecoder();// 获得解码器
byte[] by = decoder.decode(encodePass);
String str = new String(by);
MessageDigest
MessageDigest类为应用程序提供消息摘要算法的
功能,如SHA-1或SHA-256或MD5。 消息摘要是采用
任意大小的数据并输出固定长度散列值的安全单向
散列函数
// MD5加密 信息摘要算法的一种
try {
// 1.获得messageDigest对象
MessageDigest messageDigest =
MessageDigest.getInstance("MD5");
// 2.传输需要加密数据
messageDigest.update(pass.getBytes());
// 3.加密
byte[] encodeBy = messageDigest.digest();
System.out.println(Arrays.toString(encodeBy));
// 将字节数组转换成BigInteger实例
BigInteger bigInteger = new BigInteger(1,
encodeBy);
String pass1 = bigInteger.toString(16);
System.out.println(pass1);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
泛型
1、意义:与形式参数作用一样,限定数据类型
2、作用:隐式帮助进行类型转换
3、功能:
- 修饰类–>泛型类
'泛型类的字母常用:E,T,K,V' public class Hello<E>{ '泛型可以充当数据类型,也可以有setter和getter方法' private E e; '泛型充当形式参数' public void a(E e1){ System.out.println(e1); } '泛型充当返回值,加上<E>代表这个方法是一个泛型方法' public <E> E b(){ System.out.println(b); } }
- 修饰接口–>泛型接口
public interface World<E,T>{ // 接口内都是抽象方法 public abstract '泛型充当形参' void add(E e); '泛型充当返回值' T delete(int id); '泛型修饰方法' <T> T test(); }
- 泛型擦除概念:泛型是在编译的时候起作用,但在代码运行期间是没有作用的
- 泛型上限
- 让泛型继承一个类
public class Test<E extends Number>{ '传入的参数只能是Number中的数据类型' }
- 泛型通配符:?
public class test<E,T>{ public void add(Hello<?,?> hello){ '?统配任意数据类型,不需要和类中的E和T保持一致' } }
集合
集合作用和数组作用一致,用于存储多个元素数据
理论上可以存储任意引用数据类型的数据(开发中都存储相同类型的数据–>避免出现类型准换问题)
在类/接口中出现 <A>这个,代表这个类为泛型的标志–>参数化类型(形参)
代表集合里面只能存储泛型所规定的的类型的数据(限定集合元素数据类型)
?代表的是泛型的通配符
? extends 父类,限制父类,不限制子类
? super 子类,限制子类,不限制父类
集合的接口
1、Collection(是List和Set的父类)
特征:
- 用于存放单值元素
- 元素是无序的(没有索引位置)
- 元素是否可以重复要看使用的是哪个类实现的
创建集合对象
Collection<指定泛型的变量> collection = new ArrayList<指定泛型的变量>();
增加元素
collection.add(E e); // 将指定元素添加到集合中
collection.addAll(Collection<? extends E> c); // 将指定集合中的所有元素添加到此集合
删除元素
collection.remove(Object o); // 删除指定元素
collection.removeAll(Collection<?> c); // 删除指定集合中包含的所有此集合的元素
collection.removeIf(Predicate<? super E> filter) // 删除满足给定谓词的此集合的所有元素。
使用(迭代器)Iteator<T>中的 iterator()删除
remove();
查询元素
collection.size(); // 返回此集合中的元素个数
清除集合中所有的元素
collection.clear(); // 清空集合所有元素
判断元素是否存在
collection.clear(); // 清空集合所有元素contains(object o); // 如果此集合包含指定的元素,则返回 true
collection.clear(); // 清空集合所有元素isEmpty(); // 如果此集合不包含元素,则返回 true
lambda语法:(参数类型 参数名,参数类型 参数名)->{需要进行的操作}
遍历集合元素
foreach方法
for(Object obj:collection) {
//假如元素数据为hello的时候 就删除
System.out.println(obj);
}
迭代器
Iterator it = collection.iterator();//获得集合元素的迭代器 (将集合的所有元素存储到迭代器对象里面)
while(it.hasNext()) { // it.hasNext判断集合中是否还有课迭代对象
Object obj = it.next(); // it.next表示迭代对象
if(obj.equals("hello")) {
it.remove();
}
}
jdk1.8 forEach+lambda新方法
collection.forEach(obj->{
System.out.println(obj);
});
集合中存储任意类型的对象
Collection coll = new ArrayList(); // 不指定存储的数据类型 可以存储任意类型的对象
coll.add("aa"); // 存储后是Object类型
迭代器
Iterator it = coll.iterator();
while(it.hasNext()){
Object obj = it.next(); // it.next()获取的Object类型
String i = (String)obj; // 强制转换为String类型
}
集合转数组
第一种方法
Object[] objs = collection.toArray();
第二种方法 (推荐使用)
Object[] objects = new Object[collection.size()];
collection.toArray(objects);
List<T>
特征
- 存储单值元素
- 元素有序的(有索引位置)
- 元素可以重复的
包括三个子类:ArrayList<E>(重要),LinkedList<E>,Vector
E代表的是:Element 元素,实际就是一个变量
三者之间的区别:
- 底层的数据结构
ArrayList/Vector 是由动态数组进行维护。
LinkedList 是由双向链表进行维护。 - 添加 删除 查询效率
ArrayList: 查询最快
LinkedList:添加删除最快 查询较慢
Vector: 都慢 - 线程安全
ArrayList/LinkedList 都是线程不安全的
Vector 线程安全的
ArrayList
初始化容量10
List<Integer> list = new ArrayList<>();
获取
list.get(list.size()-1) // 获取最后一个元素
删除
list.remove(1); //1为索引值,删除索引为1的值并且返回被删除的索引
list.remove(new Integer(1)); // 删除一个值为1的数
修改
list.set(0, 1000); // 把第一个元素改为1000
遍历
1.
for(int index = 0,size = list.size();index<size;index++) {
System.out.println(list.get(index));
}
2.
for(Integer num:list) {
System.out.println(num);
}
3.
Iterator<Integer> it = list.iterator();
while(it.hasNext()) {
Integer num1 = it.next();
System.out.println(num1);
it.remove();
}
4.
ListIterator<Integer> listIt = list.listIterator(); // 迭代器
while(listIt.hasNext() ){
System.out.println(listIt.next());
}
5.
list.forEach(num->{
System.out.println(num);
});
linkedList
初始化对象
LinkedList<String> linkedList = new LinkedList<>();
添加元素
linkedList.add(0, "abc"); // 根据索引添加
linkedList.addFirst("a"); // 在集合第一个元素添加
linkedList.addLast("d") // 在集合最后一个元素添加
获取元素
linkedList.get(0); // 获取第一个元素
linkedList.getFirst(); // 获取第一个元素
linkedList.getLast(); // 获取最后一个元素
linkedList.peek(); // 获取第一个元素
linkedList.peekFirst(); // 获取第一个元素 列表为空,则返回 null
linkedList.peekLast();// 获取最后一个元素 列表为空,则返回 null
删除元素
linkedList.remove();//删除第一个元素
linkedList.removeFirst(); //删除第一个元素
linkedList.removeLast(); //删除最后一个元素
linkedList.remove("hello"); // 删除“hello”元素
linkedList.poll(); // 获取并删除第一个元素
linkedList.pollFirst();// 获取并删除第一个元素 列表为空,则返回 null
linkedList.pollLast();// 获取并删除最后一个元素 列表为空,则返回 null
Set
特征
- 存储单值元素
- 元素无序(没有索引位置)
- 元素不可以重复的,值必须唯一(前提: 一定要重写 equals和hashcode),默认初始容量16
包含三个子类:HashSet<T>,LinkedHashSet<T>,TreeSet<T>
区别: - 底层的数据结构
HashSet 是哈希表(哈希算法)维护,存储取出快,元素无序
LinkedHashSet 是由哈希表+双向链表维护,继承HashSet,元素是有序的 (插入顺序和 输出顺序是一致的)
TreeSet 是由二叉树(红黑树)进行维护 元素是有序的(按照自然顺序进行排列 要求集合元素数据类型必须有比较器 (实现 Comparable)) - 元素是否可以为null
HashSet/LinkedHashSet 元素可以为null
TreeSet 元素不允许为null - 线程是否安全
HashSet<T>/LinkedHashSet<T>/TreeSet<T> 都不安全
哈希表存储对象的依据是对象的哈希值和equals方法
实现方法和Collection一致
初始化对象
Set<Integer> set = new HashSet<>();
添加元素
set.add(10);
Set<User> userSet = new HashSet<>();
userSet.add(new User()); // 可以传一个对象引用,
userSet.add(new User()); // 前提: 一定要重写 equals和hashcode方法
userSet.add(new User());
遍历集合元素
set.forEach(num->{
if(num==10) {
System.out.println(num);
}
});
2、Map
存储的是一组元素数据,有key和value
Map中的key是不能重复的,value可以重复
实现类和子类:HashMap<K,V>(元素无序),LinkedHashMap<K,V>(元素有序),TreeMap<K,V>,HashTable<K,V>,CouncurrentHashMap<K,V>
区别:
- 从底层数据结构
HashMap/HashTable 哈希表维护
LinkedHashMap 哈希表和链表维护,是HashMap的子类
TreeMap 红黑树维护,元素有序的,会按照key的自然顺序进行排序
CouncurrentHashMap CAS(比较并交换) 乐观锁 + Redis - 线程安全
HashMap/LinkedHashMap/TreeMap 线程不安全
HashTable/CouncurrentHashMap 线程安全 - key和value是否可以为null
HashMap/LinkedHashMap key/value都可以为null
TreeMap key不能为null value是可以为null
HashTable/CouncurrentHashMap key/value都不能为null
HashMap,TreeMap,HashTable,LinkedHashMap
创建对象
Map<String, Integer> map = new HashMap<>();
ConcurrentHashMap<User, Integer> userMap = new ConcurrentHashMap<>();
TreeMap<User, Integer> userMap = new TreeMap<>();
Map<Integer, Integer> map = new LinkedHashMap<>(16); //需要指定容量
新增元素
map.put("key",value); // put的返回值一般情况是null,当有重复键时返回的是之前键的value值
查询元素
map.get("key"); // 返回的是value值
map.containsKey("key");
map.containsValue(value);
删除元素
map.remove("key"); // 返回的是移除之前的value值
map.remove("key", value);
替换元素
map.replace("key", value);
map.replace("key", value, 替换的value);
遍历集合元素
map.forEach((key,value)->{
System.out.println("key:"+key+"----value:"+value);
});
JDK8的新方法
Set<Entry<String, Integer>> entrySet = map.entrySet();
entrySet.forEach((Entry<String, Integer> entry)->{
//map集合的所有的元素内容 都在entry对象
System.out.println("key:"+entry.getKey()+"----value:"+entry.getValue());
});
增强for循环
for(Map.Entry<String, Integer> entry:map.entrySet()){
System.out.println("key:"+entry.getKey()+"----value:"+entry.getValue());
}
迭代器
Iterator<Entry<String, Integer>> it = entrySet.iterator();
while(it.hasNext()) {
Entry<String, Integer> entry = it.next();
System.out.println("key:"+entry.getKey()+"----value:"+entry.getValue());
}
3、Collections
集合操作工具类
对 List集合 进行二分搜索,参数传递 List集合 和 被查找的元素,集合必须是有序的
Collections.binarySearch(list,5); // 查找5出现在集合的哪个索引
找不到指定的元素内容返回值是 插入点-1
对 List集合 随机排列
Collections.shuffle(list);
List本身是线程不安全,用这个可以让它变成线程安全类
List<Integer> list = new ArrayList<>();
list = Collections.synchronizedList(list);
使用sort()方法对 list集合 进行升序排列,lambad替换 接口/抽象类
Collections.sort(list);
重写
Collections.sort(stuList, new Comparator<Student>() {
@Override
public int compare(Student stu1, Student stu2) {//排序规则
return stu1.getScore().compareTo(stu2.getScore());
}
});
IO
1、File操作
File类构造方法
// windows路径下不区分大小写
File file = new File("文件路径"); // 将路径封装成File类型对象
File file = new File("父路径","子路径"); // 可以单独操作父路径和子路径
File file = new File(File类型的路径, "子路径"); // 父路径单独分开,是一个File类型
显示与系统有关的路径分隔符
String separator = File.pathSeparator; // 是一个静态变量
打印是一个分号,在Linux下打印是一个冒号
显示与系统有关的名称分隔符
String separator = File.separator; // 静态变量
打印一个向右的斜线 \ Linux下是左斜线 /
"判断路径中是否有这个文件" + file.exists();
"判断路径中是否是一个文件夹" + file.isDirectory();
"判断路径中是否是一个文件" + file.isFile();
"判断文件是否可读:" + file.canWrite();
"创建一个文件" + file.createNewFile();
"创建一个一级目录文件夹" + file.mkdir();
"创建多级目录文件夹" + file.mkdirs();
"删除文件" + file.delete();
"剪切/重命名文件" + file.renameTo(路径,"重命名");
"获得文件最后部分的名字:" + file.getName();
"获得文件大小字节数:" + file.length();
"获得目录名:" + file.getName();
"获取文件的绝对路径:" + file.getAbsolutePath(); //返回String对象
"获取文件的绝对路径:" + file.getAbsoluteFile(); //返回File对象
"获取文件的相对路径:" + file.getPath();
"获取路径中文件和文件夹名" + file.list(); // 返回值是String[],相当于遍历
"获取路径中文件和文件夹名" + file.listFiles(); //返回值是File[],返回的是目录和文件的全路径
"获取修改的时间:" + file.lastModified();// 毫秒数
递归
注意事项:
- 递归一定要有出口
- 递归次数不能过多
- 构造方法禁止递归
public static void main(String[] args) {
File dir = new File("d:\\eclipse");
getAllDir(dir);
}
定义方法,实现目录的全遍历
public static void getAllDir(File dir){
System.out.println(dir);
//调用方法listFiles()对目录,dir进行遍历
File[] fileArr = dir.listFiles();
for(File f : fileArr){
//判断变量f表示的路径是不是文件夹
if(f.isDirectory()){
//是一个目录,就要去遍历这个目录
//本方法,getAllDir,就是给个目录去遍历
//继续调用getAllDir,传递他目录
getAllDir(f);
}else{
System.out.println(f);
}
}
}
计算斐波那契数列
public static int getFBNQ(int month){
if( month == 1)
return 1;
if( month == 2)
return 1;
return getFBNQ(month-1)+getFBNQ(month-2);
}
2、字节操作
fileInputStream
public static void test2(File file) {
jdk1.7 提供一种更加优雅的方式 去关闭流对象 try(流对象)...catch...resources
try (InputStream inputStream = new FileInputStream(file);)
{
//2.读取文件内容
byte[] by = new byte[(int)file.length()];// 1024的整数倍
int result = inputStream.read(by);//将输入流对象的数据写入到字节数组里面 返回值(读取的有效字节数)
int num = inputStream.read(); //一次读取一个字节 如果是读到文件末尾返回-1
"off 从字节数组的第几个元素开始写入 ,len: 写入多少个元素到字节数组"
int result = inputStream.read(by, 0, 4);
//将文件内容读入到字节数组
System.out.println(Arrays.toString(by));
//转换成字符串进行操作
for(byte b:by) {
System.out.print((char)b);
}
//字节数组转换成字符串
System.out.println(new String(by));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
fileOutputStream
public static void test1(File file) {
try (
// 1.创建输出流对象
"文件不存在可以自定去创建,后面为true表示追加文件后面写,不会删除文件之前已经有的内容"
OutputStream outputStream = new FileOutputStream(file,true);
) {
outputStream.write('\n'); "换行"
outputStream.write('c');"一次写一个字节内容"
byte[] by = {97,97,97,'a'};
outputStream.write(by); "依次写入byte中的字节"
outputStream.write("单价".getBytes()); "在文件中写中文"
outputStream.write(by, 0, by.length);"off从第几个元素开始写入文件 len:写多少个"
outputStream
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
3、字符操作
FileReader
public static void test3(File file) {
try (Reader reader = new FileReader(file);
) {
int result = 0;
char[] ch = new char[10];
while ((result = reader.read(ch, 0, ch.length)) != -1) {// result有效的字符数
System.out.print(new String(ch));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void test1(File file) {
try (
// 1.创建字符输出流对象
Writer writer = new FileWriter(file);) {
writer.write('我');
writer.write("我们".toCharArray());
writer.write("abc".toCharArray(), 0, 2);
writer.write("\n");
writer.append('a');
writer.flush(); "必须要刷新,不刷新就没有文件,有close()就不用刷新"
} catch (IOException e) {
e.printStackTrace();
}
}
public static void testCopy3(File sourceFile, File targetFile) {
System.out.println("COPY文件");
long start = System.currentTimeMillis(); // 计算开始copy的时间
try (
创建高效的字节输入流对象
BufferedInputStream bufferedInputStream = new BufferedInputStream(
new FileInputStream(sourceFile));
创建高效输出流对象
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
new FileOutputStream(targetFile));) {
int len = 0;
byte[] by = new byte[1024];
while ((len = bufferedInputStream.read(by)) != -1) {
bufferedOutputStream.write(by, 0, len);
}
long end = System.currentTimeMillis(); // 计算结束copy的时间
System.out.println("copy结束。。。。。。。。。。。"+(end-start));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4、输入输出流
DataInputStream/DataOutputStream
实现了一个DataInput接口,一般配合Socket使用
必须先写入文件,才能读取文件
读的顺序要和写的顺序一致
"先Write"
public static void test1(File file) {
// 用户登录
// 用户名 密码
// 保存用户名 密码内容
try (DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(file));
) {
dataOutputStream.writeUTF("jim"); "写入用户名"
dataOutputStream.writeInt(1234); "写入密码"
dataOutputStream.writeByte(20); "写入年龄"
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
"再Read"
public static void test(File file) {
try (DataInputStream dataInput = new DataInputStream(new FileInputStream(file));) {
// 读取文件内容
String name = dataInput.readUTF(); "读取UTF内容"
int id = dataInput.readInt(); "读取Int内容"
byte age = dataInput.readByte(); "读取字节内容"
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
5、Properties
特点:
- 存储键值对(一组数据),属性名—>属性值
- 读取配置文件内容,*properties
"构造方法"
Properties properties = new Properties();
"存储元素"
properties.put("key","value");
properties.setProperty("key","value"); // 建议用这个
"字节输入流对象的创建的两种方法"
InputStream inStream = PropertiesDemo.class.getResourceAsStream("user.properties");//资源文件名称
InputStream inStream = PropertiesDemo.class.getClassLoader().getResourceAsStream("com/javasm/io/user.properties");
"以.properties结尾的文件书写格式中间不能有空格!"
name=zhangSan
age=20
"流对象读取文件中的键值对,保存到集合"
properties.load(inStream);
"重写往文件里写入"
properties.store(文件写入器,"原因"); // 原因不能写中文
"获取元素"
String trueName = properties.getProperty("key");
"转成ISO8859-1读取,再转成utf-8输出"
trueName = new String(trueName.getBytes("ISO8859-1"), "utf-8");
"遍历"
Set<Entry<Object, Object>> set = properties.entrySet();
set.forEach(entry->{
System.out.println(entry.getKey()+"--------"+entry.getValue());
});
6、序列化
ObjectOutputStream 序列化流 写入
ObjectInputStream 反序列化流 读取
必须先写入文件,才能读取文件,类必须要实现Serializable接口
静态的成员变量不能序列化
transient(瞬态)修饰的成员变量不能被序列化
"构造方法"
ObjectInput objectInput = new ObjectInputStream(ObjectInputDemo.class.getClassLoader().getResourceAsStream("bin目录下配置文件名称"))
ObjectOutput objectOutput = new ObjectOutputStream(new FileOutputStream(new File("配置文件路径")))
"将指定的对象写入到文件中"
objectOutput.writeObject(user);
"从ObjectInputStream读取一个对象"
objectInput.readObject();
"字节转字符的桥" : InputStreamReader();
"字符转字节的桥" : OutputStreamWriter();
"接收用户输入的字符,并指定的编码格式"
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
"将用户的输入写入到文件中"
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File("src/b.txt")));
"指定读取的文件"
BufferedReader bufferedReader = new BufferedReader(new FileReader(new File("src/IO.txt")));
"将读取到文件的内容输出"
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
"写入固定的序列号": private static final long serialVersionUID = 1L
"一次读取一行" :bufferedReader.readLine();
"写一个换行" :bufferedWriter.newLine();
"将缓冲区的内容刷新到文件" :bufferedWriter.flush();
"将内容输出/输入":bufferedWriter.write(content);