java基础篇

Java就业方向

本册笔记Java基础 主要是javaSe的知识

发展三个方向:

1
2
3
4
5
javaEE软件工程师:电商,团购,众筹,sns,教育,金融,搜索

大数据软件工程师,大数据应用工程师,大数据算法工程师,大数据分析和挖掘。

Android软件工程师,android平台

Java开发场景举例1 -SSM

0007_韩顺平Java_Java故事_哔哩哔哩_bilibili

Java重要特点

java语言是面向对象的(OOP).

java语言是健壮的,java的强类型机制,异常处理,垃圾的自动收集等是java程序健壮性的重要保证。

java语言是跨平台性的。【即:一个编译好的class文件可以在多个系统下运行,这种特性被称为跨平台。】

java语言是解释性的。

解释性语言:javascript, PHP, java

编译性语言:C ,C++

区别是:解释性语言,编译后的代码,不能被机器直接执行,需要解释器来执行,编译性语言编译后的代码,代码文件是二进制的,可以直接被机器执行。

基础知识

转义字符

Java常用的转义字符:

1
2
3
4
5
6
7
8
9
10
11
\t	一个制表位,实现对齐的功能

\n 一个换行符

\\ 一个\

\" 一个"

\' 一个'

\r 一个回车
1
2
3
4
5
6
7
8
9
10
11
public class HelloWorld {
public static void main(String []args) {
//演示转义字符的使用
System.out.println("北京\t天津\t上海");
System.out.println("红楼梦\n三国演义\n西游记");
System.out.println("hello\\milan");
System.out.println("C:\\Windows\\System32\\cmd.exe");
System.out.println("\"要好好学习java有前途!\"");
System.out.println("好好学习\r有前途");
}
}

注释

comment(注释)用于解释程序文字就是注释,提高代码的可读性。

单行注释

1
//这是单行注释

多行注释

1
2
/*  这个是
多行注释 */

被注释的文字不会被解释器所执行

注释不可以嵌套注释

编写代码时一定要使用注释来说明每一句代码的含义,清澈明朗

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args){
//下面完成两个数的相加
//定义变量
int n1 = 10;
int n2 = 20;
//求和
int sum = n1 + n2;
//输出结果
System.out.println("结果=" + sum);
}

文档注释

注释内容可以被JDK提供的工具javadoc解析,生成一套以网页文件形式体现该程序的说明文档,一般写在类中

1
2
3
4
cmd 命令
javadoc -d 文件夹名 -xx -yy 文件名.java

-xx 和 -yy 是想要生成信息在网页文件的选项,例如author或version这些
1
2
3
4
5
6
7
8
9
/**
* @author zero
* @version 1.0
*/
public class comment{
public static void main(String[] args){
System.out.println("zero");
}
}

代码规范

类,方法的注释,要以javadoc的方式编写。

非javaDoc的注释,往往是给代码维护者看的,告诉读者为什么这么写。

使用tab操作,实现缩进,默认整体向右移动,shift + Tab 可以向左移动

运算符和等号两边习惯性加一个空格。 比如 2 + 4 * 5 + 345 - 89.

源文件使用utf-8编码。

行宽度不要超过80字符。

代码编写次行风格和行尾风格。(个人偏向行尾风格)

DOS命令

Dos: Dish Operating System 磁盘操作系统,简单说以下windows的目录结构。

相对路径和绝对路径

1
2
3
C:\user\Zero> cd Desktop //相对路径
C:\user\Zero> start D:\资料\java文件\java复习100题.docx //绝对路径

一个简单的批处理文件

1
2
3
4
@echo off // 显示路径和盘符
echo hello world //输出helloworld
pause //结束之前所有操作,可以展示窗口

计算程序

1
2
3
4
5
@echo off
set /a var = 1 + 2 //将计算结果存储到一个变量中
echo %var% //使用echo命令输出 格式是%var%
pause

创建用户

1
2
3
4
5
6
7
@echo off
echo %1 //在控制台打开文件添加跟随的参数1就是%1
echo %2 //在控制台打开文件添加跟随的参数2就是%2

net user %1 %2 /add
pause

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
dir 当前目录下的所有目录和文件
cd /D c: 切换盘符
cd.. 切换上一级
cd/ 切换到根目录
cls 清除屏幕
tree D: 展示D盘下的所有文件,以树的形式展示
md 创建目录
rd 删除目录
copy 复制文件
del 删除文件
echo 输出一串文本内容
echo hello > C:\a.txt 将文本内容另存到这个路径的一个文件上,会覆盖之前文件的内容
echo hello >> C:\a.txt 将文本内容追加到这个路径的一个文件上
type 在终端查看文本文件的内容
move 剪切文件
ipconfig 显示子网掩码和无线网络
netstat -an 显示所有的网络连接和状态

calc 计算器
notepad 记事本
explorer 浏览器
set /a 1 + 3 算术计算
start 启动一个程序
命令 && 命令 同时执行两条命令
命令 || 命令 执行第一个或者第二个
net user 查看当前用户
mkdir 创建目录
命令1 | 命令2 命令2作为命令1的输入参数运行命令1
dir | find ".txt" 查找当前目录后缀为txt的文件
netstat -an | find "ESTABLISHED" 筛选已经连接的网络端口
命令 /? 查看该命令的帮助
命令 /help 查看帮助信息

变量常量

变量是程序的基本组成单位

1
2
3
4
5
6
7
public static void main(String[] args){
int i = 1; //定义了一个变量,类型int整型,名称是i
int j = 3;
j = 89;
System.out.println(i);
System.out.println(j);
}

变量相当于内存中一个数据存储空间的表示,你可以把变量看作一个房间的门牌号,通过门牌号我们可以找到房间,而通过变量名可以访问到变量的值。

1
2
3
4
5
6
7
8
9
//记录人的信息
public static void main(String[] args){
int age = 20;
double score = 98.3;
char gender = '男';
String name = "king";
System.out.println("人的信息如下:\n" + age +"\n"+ score +"\n"+ gender +
"\n"+ name);
}
  • 变量表示内存中的一个存储区域,不同的变量,而理性不同,占用的空间大小不同。
  • int 占用4个字节 double 占用8个字节
  • 该区域有自己的名称[变量名]和类型[数据类型]
  • 变量必须先声明,后使用
  • 在同一个作用域中不能有重名的变量

数据类型

下标列出了java各个类型的默认值和大小占用。

数据类型 默认值 占用字节
byte 0 1
short 0 2
int 0 4
long 0L 8
float 0.0f 4
double 0.0d 8
char ‘u0000’ 2
String(or any object) null
boolean false 1

整数类型

整形的类型

类型 占用存储空间 范围
byte[字节] 1字节 -128~127
short[短整型] 2字节 -(2^15)~2^15-1
int[整形] 4字节 -2^31~2^31-1
long[长整型] 8字节 -2^63~2^63-1

整数类型细节

java各整数类型有固定的范围和字段长度,不受操作系统的影响,保证java程序的移植性。

Java的整形常量默认为int型,声明long型常量需要在后面加L或l.

java程序中变量大多使用int型,非特殊情况不使用long类型。

bit是最小的存储单位,byte是计算即中基本存储单元,1byte = 8 bit.

浮点类型

基本介绍

java的浮点类型可以表示一个小数,比如 123.4, 7.8, 0.12等

浮点型的分类

类型 占用存储空间 范围
单精度float 4字节 -3.403E38 ~ 3.403E38
双精度double 8字节 -1.798E308 ~ 1.798E308

说明一下

关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位

尾数部分可能丢失,造成精度损失(小数都是近似值)。

浮点类型使用细节

  1. 与整数类型类似,java的浮点类型也有固定的范围和字段长度,不受具体OS的影响,[float 4 个字节 double是 8个字节]
  2. java的浮点型常量(具体值)默认是double类型,声明float型常量,需要在数据中加一个’f’.
  3. 浮点型常量有两种表示形式:十进制数形式:5.12 , 512.0f , .512(必须有小数点) 科学计数法形式:5.12e2[5.12*10的2次方] 5.2E-2[5.2/10的2次方]
  4. 通常情况下,应该使用double型,因为它比float型更精确
  5. 浮点型使用陷阱:2.7 和 8.1 / 3 比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Main {
public static void main(String []args) {
float num2 = 1.1f;
double num3 = 1.2;
double num4 = 1.3f;
double num5 = .4;//等价 0.123
System.out.println(num5);
System.out.println(5.12e2);//512.0
System.out.println(5.12E-2);//0.0512
//使用陷阱: 2.7 和 8.1 / 3比较
//看看一段代码
double num11 = 2.7;
double num12 = 8.1 / 3;
System.out.println(num11);
System.out.println(num12);
//得到一个重要的知识点:当我们对运算结果是小数的进行相等判断时,要小心
if(num11 == num12){
System.out.println("相等");//不会输出
}
//应该是以两个数的差值的绝对值在某个精度范围内判断
if(Math.abs(num11-num12) < 0.00001){
System.out.println("similarly");//会输出
}
//细节:如果直接赋值的两个小数不是计算得出的,是可以判断相等
}
}

JavaAPI文档

API(Application Programming Interface),应用程序编程接口,是java提供的基本编程接口(java提供的类还有相关的方法),中文在线文档: Java 8 中文版 - 在线API中文手册 - 码工具 (matools.com)

Java语言提供了大量的基础类,因此Oracle公司也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法。

字符类型

基本介绍

字符类型可以表示单个字符,字符类型是char,char是两个字节(可以存放汉字),多个字符我们用字符串String(后面详细讲解String)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Main {
public static void main(String []args) {
float num2 = 1.1f;
double num3 = 1.2;
double num4 = 1.3f;
double num5 = .4;//等价 0.123
System.out.println(num5);
System.out.println(5.12e2);//512.0
System.out.println(5.12E-2);//0.0512
//使用陷阱: 2.7 和 8.1 / 3比较
//看看一段代码
double num11 = 2.7;
double num12 = 8.1 / 3;
System.out.println(num11);
System.out.println(num12);
//得到一个重要的知识点:当我们对运算结果是小数的进行相等判断时,要小心
if(num11 == num12){
System.out.println("相等");//不会输出
}
//应该是以两个数的差值的绝对值在某个精度范围内判断
if(Math.abs(num11-num12) < 0.00001){
System.out.println("similarly");//会输出
}
//细节:如果直接赋值的两个小数不是计算得出的,是可以判断相等
}
}

字符类型使用细节

  1. 字符常量是用单引号('')括起来的单个字符。例如: char c1 = 'a'; char c2 = '中'; char c3 = '9';

  2. Java中还允许使用转义字符\'来将其后的字符转变为特殊字符型常量。例如:char c3 = '\n';//'\n'表示换行符.

  3. 在java中,char的本质是一个整数,在输出时,是unicode码对应的字符。http://tool.chinaz.com/Tools/Unicode.aspx

  4. 可以直接给char赋一个整数,然后输出时,会按照对应的unicode字符输出[97]

  5. char类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码.

字符类型本质探讨

  1. 字符型 存储到 计算机中,需要将字符对应的码值(整数)找出来,比如'a'

存储: 'a'==> 码值 97 ==> 二进制 ==> 存储

读取:二进制 => 97 ===> 'a' => 显示

  1. 字符和码值的对应关系是通过字符编码表决定的(是规定好)

·介绍一下字符编码表[sublime测试]

ASCII (ASCII 编码表 一个字节表示,一个128个字符)

Unicode (Unicode 编码表 固定大小的编码 使用两个字节来表示字符,字母和汉字统一都是占用两个字节,这样浪费空间)

utf—8 (编码表,大小可变的编码 字母使用1个字节,汉字使用3个字节)gbk (可以表示汉字,而且范围广,字母使用1个字节,汉字2个字节)gb2312(可以表示汉字,gb2312<gbk)

big5码(繁体中文,台湾,香港)

布尔类型

基本介绍

  1. 布尔类型也叫boolean类型,booolean类型数据只允许取值true和false,无 null

  2. boolean类型占1个字节。

  3. boolean 类型适于逻辑运算,一般用于程序流程控制[这个后面会详细介绍]:if条件控制语句;

while循环控制语句;✓ do-while循环控制语句; for循环控制语句

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main{
public static void main(String[] args){
//演示判断成绩是否通过的案例
//定义一个布尔变量
boolean isPass = true;
if(isPass = true){
System.ou.println("考试通过");
}else{
System.out.println("下次努力");
}
}
}

基本数据自动类型转换

自动类型转换

当java程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换。

数据类型按精度(容量)大小排序为(背,规则)

char -> int -> long -> float -> double

byte -> short -> int -> long -> float -> double

1
2
3
4
5
6
7
8
9
public class AutoConvert{
public static void main(String[] args){
int num = 'a';//char -> int
double d1 = 80;//int -> double
System.out.println(num);//97
System.out.println(d1);//80
}
}

自动类型转换注意和细节

1.有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。

2.当我们把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报

错,反之就会进行自动类型转换。

3.(byte,short)和char之间不会相互自动转换。

4.byte,short,char 他们三者可以计算,在计算时首先转换为int类型。

5.boolean 不参与转换

6.自动提升原则:表达式结果的类型自动提升为 操作数中最大的类型

API常用类

包装类和基本数据的转换

jdk5前的手动拆箱和手动装箱的方式,装箱 基本类型 -> 包装类型,拆箱 包装类型 -> 基本类型

jdk5后使用自动的拆箱和装箱方式

自动装箱调用的是valueOf方法,例如Integer.valueOf()

手动拆箱调用的是value方法,例如Integer(包装类实例名).intValue()

类型转换调用的是parse方法,例如Integer.parseInt()

Java 基本数据类型与包装类之间的转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Test {
public static void main(String[] args) {
int i1 = 1;
//手动装箱操作
Integer integer = Integer.valueOf(i1);
//手动拆箱操作
int i2 = integer.intValue();
int j = 2;
//自动装箱,底层调用了valueOf()
Integer integer1 = j;
//自动拆箱,底层调用了intValue()
int k = integer1;
//类型转换操作
try {
i1 = Integer.parseInt("1");
} catch (NumberFormatException e) {
System.out.println("数字格式异常");
}
}
}

基本数据类型和String之间的相互转换

1
2
3
4
5
6
7
8
Integer i = 123;//自动装箱
//方式1
String str1 = i + "";
//方式2
String str2 = i.toString();//调用Integer的toString方法
//方式3
String str3 = String.valueOf(i);//调用String.valueOf方法

Integer包装类和Character的常用方法

1
2
3
4
5
6
7
8
9
10
11
//使用IDEA编写代码
Intger.MIN_VALUE.sout //.sout可以让数据输出 Integer.MIN_VALUE: 返回最小值
Intger.MAX_VALUE.sout //Intger.MAX_VALUE: 返回最大值
Character.isDigit(char) //判断传入的char类型形参是否是数字
Character.isLetter(char) //判断传入的char类型形参是否是字母
Character.isUpperCase(char) //判断传入的char类型形参是否是大写
Character.isLowerCase(char) //判断传入的char类型形参是否是小写
Character.isWhitespace(char) //判断传入的char类型形参是否是空格
Character.toUpperCase(char) //将传入的char类型形参转为大写
Character.toLowerCase(char) //将传入的char类型形参转为小写

String类

String类对象是用于保存字符串,也就是一组字符序列

字符串常量对象是用双引号括起的字符序列。例如:”你好” 、”12.97”、“boy”等

字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节

String类的常用构造器:

1
2
3
4
5
String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a,int startIndex,int count);

String类默认继承Object类,实现CharSequence字符序列,Serializble序列化,Comparable可比较

创建String对象的方式

1
2
3
4
5
//方式1
String s = "String";//将s实例指向常量池的"String"常量
//方式2
String s = new String("String");//在堆中创建一个String类对象,String类的对象的value属性指向常量池"String"常量

方式一:先从常量池查看是否有”String”数据空间,如果有,直接指向;如果没有则重新创建,然后指向常量。s实例最终指向的是常量池中的空间地址

方式二:先在堆中创建空间,里面维护了value属性,指向常量池中的”String”数据空间,如果常量池中没有”String”,重新创建,如果有,直接通过value指向,最终指向的是堆中的空间地址

测试题

1
2
3
4
5
String a = "abc";
String b = "abc";
System.out.println(a.equals(b));//返回的结果是?
System.out.println(a == b);//返回的结果是?

答案为true,因为是比较两个对象指向的值是否想相等

答案为true,因为比较的是两个实例引用指向的是否是同一个地址

1
2
3
4
5
String a = new String("abc");
String b = new String("abc");
System.out.println(a.equals(b));//返回的结果是?
System.out.println(a == b);//返回的结果是?

答案为true和false,解释如上一样

1
2
3
4
5
6
7
String a = "abc";
String b = new String("abc");
System.out.println(a.equals(b));//返回的结果是?
System.out.println(a == b);//返回的结果是?
System.out.println(a == b.intern());//返回的结果是?
System.out.println(b == b.intern());//返回的结果是?

答案为true,false,true , false

intern是一个返回常量地址的方法,如果引用实例使用了intern()方法,会找到他最终指向的字符串常量地址并返回。

详细说明可以查询API文档,这里只是简单赘述。

a实例和b.intern比较时,比较的是两个地址是否相等,地址正好相等,返回true

b实例和b.intern比较时,也是比较地址,但由于b指向的是一个String对象,所有两个地址不一样,为false

1
2
3
4
5
6
7
8
9
String s1 = "abc";
String s2 = "java";
String s3 = new String("java");
String s4 = "java";
System.out.println(s2 == s3);//返回的结果是?
System.out.println(s2 == s4);//返回的结果是?
System.out.println(s2.equals(s3));//返回的结果是?
System.out.pritnln(s1 == s2);//返回的结果是?

答案为false,true,true,false。

1
2
3
4
5
6
7
8
9
10
Person p1 = new Person();
p1.name = "abc";
Person p2 = new Person();
p2.name = "abc";
System.out.println(p1.name.equals(p2.name));//返回的结果是?
System.out.println(p1.name == p2.name);//返回的结果是?
System.out.println(p1.name == "abc");//返回的结果是?
String s1 = new String("abcde");
String s2 = new String("abcde");
System.out.println(s1 == s2);//返回的结果是?

答案为true,true ,true ,false

String特性

String 是一个final类,代表不可变的字符序列

字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的。

String s1 = “hello”;

s1 = “haha”; 问创建了几个对象?

答案一共是创建了两个对象,那么来点难度的

1
2
3
4
String a = "hello" + "abc" //问一共创建了几个对象
String b = "hello";
String c = "abc";
String d = b + c;//问一共创建了几个对象

答案一个对象和四个对象

在两个进行相加并赋值时,编译器会优先计算好结果,将”helloabc”赋值给a然后再编译为可执行class

在两个实例引用相加时,会调用底层StringBuilder的append方法将变量b拼接给d,然后将变量c拼接给d、

StringBuiler对象存在堆中,调用append方法进行拼接。b对象c对象stringBuider对象和d对象,其实一共是四个对象。

当变量相加时,在堆中操作,当常量相加时,是在池中。

1
2
3
4
5
6
String s1 = "abc"
String s2 = "java";
String s3 = "abcjava";
String s4 = (s1 + s2).intern();
System.out.println(s3 == s4);
System.out.println(s3.equals(s4));

答案为true,true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Test{
String str = new String("abc");
final char[] ch = {'j','a','v','a'};
public static void main(String[] args){
Test test = new Test();
test.change(test.str,test.ch);
System.out.print(test.str + "and");//请问输出什么?
System.out.println(test.ch);//请问输出什么?
}

public void change(String str,char ch[]){
str = "java";
ch[0] = 'h';
}
}

答案为abcandhava,因为str更改是一个传入的局部变量,并不能影响外面的str。但是ch因为实在堆中,并且他是一个final类型的变量,所有在更改时指针不会发生变化,并且成功更改。最后拼合字符串就是这个结构

String方法

由于String类是保存字符串常量的,每次更新都需要重新开辟空间,效率较低,因此java设计者还提供了StringBuilder和StringBuffer来增强String的功能,并提高效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
equals()区分大小写,判断内容是否相等
equalsIgnoreCase()忽略大小写的判断内容是否相等
length()获取字符的个数,字符串的长度
indexOf()获取字符在字符串中的第1次出现的索引,从0开始,如果找不到就返回-1
lastIndexOf()获取字符在字符串中的最后一次出现的索引,从0开始,如果找不到就返回-1
subString()获取指定范围的字串
trim()去前后空格
charAt()获取某索引处的字符,注意不能使用Str[index]这种方式
toUpperCase()将字符串转换为大写
toLowerCase()将字符串转换为小写
concat()拼接字符串
replace()替换字符串中的字符
split()分割字符串,对于某些分割字符,我们需要转义比如| \\ 等
compareTo()比较两个字符串的大小
toCharArray()转换成字符数组
format()格式化字符串 %s字符串 %d整数 %c字符 %.2f浮点型,保留两位小数

String增强类

StringBuffer类

java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删

很多方法与String相同,但StringBuffer是可变长度的

StringBuffer相对于String来说是一个容器,StringBuffer是一个final类,实现了serializable,可以进行序列化,即网络传输。继承了抽象类AbstractStringBuffer,AbstractStringBuffer中的属性char[] value存放的字符序列,该value存放的数据是堆中的,每次增加或修改时不需要更改地址,所以效率要高于String。

String VS StringBuffer

String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 //private final char value[];

StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高 //char[] value;//这个存放在堆中

开发中需要将String类和StringBuffer类进行转换,看看如何实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Test {
public static void main(String[] args) {
String str = "abc";
//返回的才是StringBuffer类的对象,不影响原来的str变量
StringBuffer stringBuffer = new StringBuffer(str);
//使用append方法
stringBuffer1 = stringBuffer.append(str);

//StringBuffer -> String
StringBuffer hello = new StringBuffer("Hello");
//第一种,使用StringBuffer的toString()方法
String s = hello.toString();
//第二种,使用String类的构造器
String s1 = new String(hello);
}
}

StringBuffer类的常用方法

1
2
3
4
5
6
StringBuffer.append(String); 在当前对象尾部追加字符串
StringBuffer.delete(index start,index end)删除从索引start到索引end之间的字符
StringBuffer.replace(intdex start,index end,String replace)在索引start到end之间替换成replace的字符
StringBuffer.indexOf(String src)返回该子字符串在字符串中第一次出现的索引,找不到返回-1
StringBuffer.insert(index insert,String s)在字符串中的索引为insert位置插入s字符串
StringBuffer.length()返回字符串的长度

StringBuilder类

一个可变的字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步。StringBuilder不是线程安全,此类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候,如果可能,建议优先使用该类,因为在大多数实现中,他比StrinBuffer要块。

在StringBuilder上的主要操作append和insert方法,可重载这些方法,以接收任意的数据类型

StringBuilder和StringBuffer均可代表可变的字符序列,方法是一样的,所以使用和StringBuffer一样。

StringBuilder是final类型,继承了AbstractStringBuilder,它有一个内置属性char[] value,内容存到value。

实现了serializable接口,可以序列化,序列化可以保存数据类型和数据本身到文件中。

String ,StringBuffer和StringBuilder的比较

StringBuilder和StringBuffer非常类似,均可代表可变的字符序列,而且方法也一样

String 不可变的字符序列,效率低,但是复用性高

StringBuffer 可变字符序列,效率较高(增删)、线程安全、(由于它的方法都是使用synchronized来修饰,所以线程安全)。

StringBuilder 可变字符序列,效率最高,线程不安全

String的注意点:

1
2
3
4
String s = "a";//创建了一个字符串
s += "b";
实际上在原来的a字符串对象已经丢弃了,现在又产生了一个字符串s + "b",(也就是"ab").如果多次执行这些改变串内容的操作,会导致大量副本字符串对象停留在内存中,降低效率,如果这样的操作放到循环中,会极大影响程序的性能
所以我们如果对字符串进行大量修改,不要使用String类

使用结论

如果字符串存在大量的修改操作,一般使用StringBuffer或StringBuilder

如果字符串存在大量的修改操作,并存在单线程的形况,使用StringBuilder

如果字符串存在大量的修改操作,并存在多线程的情况,使用StringBuffer

如果我们的字符串很少修改,但是经常被调用,使用String,比如配置信息等

StringBuilder效率大于StringBuffer,StringBuffer效率大于String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Test{
public static void main(String[] args){
String text = "";
long startTime = 0L;
long endTime = 0L;
StringBuffer buffer = new StringBuffer("");
StringBuilder builder = new StringBuilder("");
startTime = System.currentTimeMillis();
for(int i = 0;i < 20000;i++){//StringBuffer拼接2万次
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for(int i = 0;i < 20000;i++){//StringBuilder拼接2万次
builder.append(String.valueOf());
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for(int i = 0;i < 20000;i++){
text = text + i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime));
}
}

在这段代码可以体现三个类的执行总时间,可以直观的查看效率

Math类

Math类

​ Math类包含用于执行基本数学运算的方法,如初等指数,对数,平方根,三角函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
abs(double a)返回double值的绝对值
abs(float a)返回float值得绝对值
abs(int a)返回int值得绝对值
abs(long a)返回long值得绝对值
acos(double a)返回一个值反余弦,返回得角度范围在0.0到pi之间
asin(double a)返回一个值的反正弦,返回的角度范围在-pi/2到pi/2之间
atan(double a)返回一个值的反正切,返回的角度范围在-pi/2到pi/2之间
cbrt(double a)返回一个double值得立方根
sqrt(int a)返回一个a开方后得结果
min(int a,int b)返回a与b之间得最小值
max(int a,int b)返回a与b之间得最大值
random()返回0-1之间的随机浮点数
pow(int a,int mi)返回a的mi次方
ceil(double a)返回一个向上取整的double值
floor(double a)返回一个向下取整的double值
round(double a)返回一个四舍五入的double值

Arrays类

Arrays类

Arrays类用于提供一些对于数组来使用的遍历操作。

1
2
3
4
5
6
7
Arrays.toString()返回数组的字符串形式
Arrays.sort()自然排序数组
Arrays.binarySearch()二分搜索法查找元素
Arrays.copyOf()拷贝数组副本
Arrays.fill()数组元素的复制
Arrays.equals()比较两个数组内容是否完全一致
Arrays.asList()将数组转换为一个集合

System类

system类的常用方法和案例

exit()退出当前程序并返回退出码,默认为0

arrayCopy()复制数组元素,这个是Arrays.copyOf()的底层方法,理论上比copyOf更快一些

arrayCopy(src,0,dest,0,3)形参解释: 原数组,原数组开始拷贝的下标,目标数组,目标数组开始粘贴的下标,拷贝的数量

currentTimeMillens()返回当前时间距离1970-1-1的毫秒数

gc()运行垃圾回收机制

BigInteger和BigDecimal类

BigInteger适用于比较大的整型

BigDecimal适用于保存精度更高的浮点型小数

常见方法

1
2
3
4
5
add() 加
subtract() 减
multiply() 乘
divide() 除

第一代日期类

Date类型:精确到毫秒,代表特定的瞬间

SimpleDateFormat:格式化和解析日期的类

SimpleDateFormat​格式化或解析日期的具体类,它允许进行格式化日期和文本 ,解析(文本->日期)和规范化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.text.SimpleDateFormat;
import java.util.Date;

public class Date_ {
public static void main(String[] args){
//获取当前系统时间
//Date包在javautil包
Date d1 = new Date();
System.out.println("当前日期:" + d1);
//通过毫秒数来获取时间
Date d2 = new Date(2714638);
System.out.println(d2);
//创建simpleDateFormat对象,格式化属于我们的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
String format = sdf.format(d1);
System.out.println(format);
//可以把一个格式化的String转成对应的Date
String s = "1996年01月01日 10:20:30 星期一";
try{
Date parse = sdf.parse(s);
System.out.println(sdf.format(parse));
}catch(Exception e){
System.out.println("转换有异常");
}
}
}


第二代日期类

主要就是Calender类(日历)

public abstract class Calender extends Object implements Serializable,Cloneable,Comparable

Calender类是一个抽象类,它为特定瞬间与一组YEAR,MONTH,DAY_OF_MONTH.HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Calendar;

public class Calendar_ {
public static void main(String[] args){
//calendar是一个抽象类,并且构造器是private
//可以通过getInstance()来获取实例
//Calendar没有提供对应的格式化的类,因此需要程序员自己组合来输出(灵活)
//如果我们需要按照24小时进制来获取时间,Calendar.HOUR == 改成Canendar.HOUR_OF_DAY
Calendar c = Calendar.getInstance();
//System.out.println(c);
//获取日历对象的某个日历字段
System.out.println("年" + c.get(Calendar.YEAR));
System.out.println("月" + c.get(Calendar.MONTH));
System.out.println("日" + c.get(Calendar.DAY_OF_MONTH));
System.out.println("小时" + c.get(Calendar.HOUR_OF_DAY));
System.out.println("分钟" + c.get(Calendar.MINUTE));
System.out.println("秒" + c.get(Calendar.SECOND));
//需要自己拼合才能查看时间
System.out.printf("现在是%d年%d月%d日%d小时%d分钟%d秒",c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH),c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE),c.get(Calendar.SECOND));
}
}

第三代日期类

前两代日期不足的分析

JDK1.0中包含了一个Java.Util.Date类,但是它的大多数方法已经在JDK1.1引入Calendar类之后被弃用了,而Calendar类之后也被启用了,而calendar存在的问题是:

可变性:像日期和时间这样的类应该是不可变的。

偏移性:Date中的年份是从1900开始的,而月份都从0开始

格式化:格式化只对Date有用,Calendar则不行

此外它们也不是线程安全的:不能处理闰秒等(每隔两天,多出1s)

LocalDate(日期/年月日),LocalTime(时间/时分秒) ,LocalDateTime(日期时间/年月日时分秒)JDK8加入

LocalDate只包含日期,可以获取日期字段

LocalTime只包含时间,可以获取时间字段

三代日期类的基本使用_林小汤的博客-CSDN博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;
import java.io.*;

@SuppressWarnings("all")
/**
* @author Zero02
* @date 2022-08-31 下午 02:28
* @description 本地时间
* @package PACKAGE_NAME
*/

public class LocalTime_ {
public static void main(String[] args) {
//使用now()返回表示日期当前的对象
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//使用DateTimeFormatter对象来进行格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//输出格式化的日期
String format = dateTimeFormatter.format(now);
System.out.println("格式化的日期:" + format);
//拿到所有的信息
System.out.printf("%d年%d月%d日%d时%d分%d秒",now.getYear(),now.getMonthValue(),now.getDayOfMonth(),now.getHour(),now.getMinute(),now.getSecond());
System.out.println();
//可以获取年月日
LocalDate now1 = LocalDate.now();
//可以获取时分秒
LocalTime now2 = LocalTime.now();
//提供plus或minus方法可以对当前时间进行加或者减
//看看890天后,是什么时候把年月日时分秒
LocalDateTime localDateTime = now.plusDays(890);
System.out.println(localDateTime);
//看看在3456分钟之前是什么时候
LocalDateTime localDateTime1 = now.minusMinutes(3456);
System.out.println(dateTimeFormatter.format(localDateTime1));
}
}


DateTimeFormat格式日期类

DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式);

String str = dtf.format(日期对象);

Instant时间戳

类似于Date

提供了一系列和Date类转换的格式

Instant -> Date;

Date date = Date.From(instant);

Instant instant = date.toInstant();

案例演示

通过静态方法now()表示当前时间戳的对象

Instant now = Instant.now();

System.out.println(now);

通过from可以把Instant转为Date

Date date = Date.from(now);

通过date的toInstant()可以把date转成Instant对象

Instant instant = date.toInstant();

1
2
3
4
5
6
7
//通过静态方法now()获取表示当前时间戳的对象
Instant now = Instant.now();
System.out.println(now);
//通过from可以把Instant转为Date
Date date = date.from(now);
//通过date的toInstant可以把date转为Instant对象
Instant instant = date.toInstant();

LocalDateTime的更多方法

isLeapYear()是否是闰年

plus()方法车市增加时间的某个部分

使用minus方法测试查看一年前和一年后的日期