Java常用类学习
内部类
内部类:在一个类的内部再定义一个完整的类
内部类特点:
- 编译之后可生成独立的字节码文件,含$符号
- 内部类可以直接访问外部类的私有成员,而不破坏封装
- 可为外部类提供必要的内部功能组件
package com.yushuo.inner;
public class Outer {
private String name;
class Inner {
public void show(){
//内部类直接访问外部类私有变量
System.out.println(name);
}
}
}
内部类分类:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
成员内部类
成员内部类:
-
在类的内部定义,与实例变量、实例方法同级别的类
-
外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
package com.yushuo.inner.demo02; //外部类 public class Outer { private String name = "张三"; private int age = 20; //内部类,可以添加public等修饰符 class Inner { private String address = "北京"; private String phone = "110"; public void show(){ //打印外部类属性 System.out.println(name); System.out.println(age); //打印内部类属性 System.out.println(address); System.out.println(phone); } } } package com.yushuo.inner.demo02; public class Application { public static void main(String[] args) { /** * 通过外部类实例化内部类 * 1、创建外部类 * 2、外部类.new创建内部类 */ Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.show(); //一步到位 Outer.Inner inner1 = new Outer().new Inner(); inner1.show(); } }
-
当外部类、内部类存在重名属性时,会优先访问外部类属性
package com.yushuo.inner.demo02; //外部类 public class Outer { private String name = "外部类"; private int age = 20; //内部类,可以添加public等修饰符 class Inner { private String address = "北京"; private String phone = "110"; private String name = "内部类"; public void show(){ System.out.println(name);//内部类 //最好加前缀以方便区分 System.out.println(this.name);//内部类 //访问外部类变量 System.out.println(Outer.this.name);//外部类 } } }
-
成员内部类不能定义静态成员,但是可以有静态常量
静态内部类
在成员内部类基础上添加static关键字,且只有静态内部类可以用static关键字修饰
- 不依赖外部类对象,可以直接创建或通过类名访问,可声明静态成员
package com.yushuo.inner.demo03;
//外部类
public class Outer {
private String name = "外部类";
private int age = 20;
//静态内部类,级别和外部类相同
static class Inner {
private String address = "北京";
private String phone = "110";
//静态成员
private static int count = 10;
public void show(){
//调用静态内部类属性和方法
System.out.println(address);
System.out.println(phone);
/**
* 调用静态内部类的静态属性
* 通过类名访问
* 直接访问也行,但是推荐使用类名访问
*/
System.out.println(Inner.count);//推荐
System.out.println(count);//也行,不建议
/**
* 调用外部类对象步骤:
* 1、创建外部类对象
* 2、通过外部类对象访问
*/
Outer outer = new Outer();
System.out.println(outer.age);
System.out.println(outer.name);
//一步到位
System.out.println(new Outer().age);
System.out.println(new Outer().name);
}
}
}
package com.yushuo.inner.demo03;
public class Application {
public static void main(String[] args) {
//直接创建静态内部类对象
Outer.Inner inner = new Outer.Inner();
inner.show();
}
}
局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
- 限制类的使用范围
package com.yushuo.inner.demo04;
//外部类
public class Outer {
private String name = "内部类";
private int age = 10;
public void run(){
//定义局部变量
String address = "北京";
/**
* 局部内部类,与局部变量同级别
* 局部内部类,注意不能添加任何的访问修饰词
* 局部成员都不能添加任何访问修饰词
*/
class Inner {
/**
* 局部内部类中的属性,都是常量
* 局部内部类中不能有静态成员,除非是常量
*/
private String phone = "110";
final static int anInt = 10;
private int a = 1;
public void show(){
/**
* 非静态方法中内部类访问外部类属性:
* 直接访问,但是希望带上Outer.this
* 如果是静态方法,需要对实例化外部类
*/
System.out.println(Outer.this.name);
System.out.println(Outer.this.age);
//访问内部类属性,建议加上this
System.out.println(this.phone);
/**
* 内部类访问外部方法的局部变量
* jdk1.7要求必须是常量final
* jdk1.8之后会默认添加final
* 因此address是常量,无法修改
*/
System.out.println(address);
}
}
//方法内创建局部内部类对象
Inner inner = new Inner();
inner.show();
}
}
package com.yushuo.inner.demo04;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//调用方法,方法中创建内部类以调用内部类
outer.run();
}
}
匿名内部类
匿名内部类:
- 没有类名的局部内部类(一切特征都与局部内部类相同)
- 必须继承一个父类或者实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
- 优点:减少代码量;缺点:可读性较差
package com.yushuo.inner.demo05;
public class Application {
public static void main(String[] args) {
//多态,父类引用指向子类
UserService userService1 = new UserServiceImpl();
//此处是非静态方法,执行子类的方法
userService1.Service();
class Impl implements UserService{
@Override
public void Service() {
System.out.println("局部内部类");
}
}
//使用局部内部类创建对象
UserService userService2 = new Impl();
userService2.Service();
//使用匿名内部类优化(相当于创建了局部内部类)
//可以写多个匿名内部类
UserService userService3 = new UserService() {
@Override
public void Service() {
System.out.println("匿名内部类");
}
};
userService3.Service();
}
}
Object类
Object类:
- 超类、基类,是所有类的直接或间接父类,位于继承树的最顶层
- 任何类,如果没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
- Object类中所定义的方法,是所有对象都具备的方法
- Object类型可以存储任何对象
- 作为参数,可以接受任何对象
- 作为返回值,可以返回任何对象
getClass()方法
- public final Class<?> getClass(){}
- 返回引用中存储的实际对象类型
- 应用:通常用于判断两个引用中实际存储对象类型是否一致
package com.yushuo.object.demo01;
public class Application {
public static void main(String[] args) {
//getClass()方法
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
//判断s1和s1是否是同一个类型
Class class1 = s1.getClass();
Class class2 = s2.getClass();
if (class1 == class2){
System.out.println("s1和s2属于同一个类型");
} else {
System.out.println("s1和s2不属于同一个类型");
}
}
}
hashCode()方法
- public int hashCode() {}
- 返回该对象的哈希码值
- 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值
- 一般情况下相同对象返回相同的哈希码
package com.yushuo.object.demo02;
public class Student {
private String name;
private int age;
//无参构造器
public Student() {
}
//有参构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.yushuo.object.demo02;
public class Application {
public static void main(String[] args) {
//hashCode()方法
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
Student s3 = s1;
/**
* s1和s2是不同的对象,s1和s3是相同的对象
* 不同对象开辟的空间不同,因此地址不同
* s1和s2返回的hash值不同
* s1和s3返回的hash值相同
*/
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
}
}
toString()方法
- public String toString() {}
- 返回该对象的字符串表示(表现形式)
- 可以根据程序需求覆盖该方法,如:展示对象各个属性值
- 快捷键 Alt + Insert
package com.yushuo.object.demo03;
public class Student {
private String name;
private int age;
//无参构造器
public Student() {
}
//有参构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//重写以输出属性值
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.yushuo.object.demo03;
public class Application {
public static void main(String[] args) {
//toString()方法
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
/**
* toString()返回结果(如果不重写)
* 类名全称@地址的hash值
* s1的返回值:com.yushuo.object.demo03.Student@1b6d3586
* s2的返回值:com.yushuo.object.demo03.Student@4554617c
*/
System.out.println(s1.toString());
System.out.println(s2.toString());
}
}
equals()方法
- public boolean equals(Object obj) {}
- 默认实现为(this == obj),比较两个对象地址是否相同
- 可进行覆盖,比较两个对象的内容是否相同
package com.yushuo.object.demo04;
public class Student {
private String name;
private int age;
//无参构造器
public Student() {
}
//有参构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.yushuo.object.demo04;
public class Application {
public static void main(String[] args) {
//equals()方法,判断两个对象是否相等,即地址是否相同
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
Student s3 = s1;
Student s4 = new Student("张三",20);
System.out.println(s1.equals(s2));//false
System.out.println(s1.equals(s3));//true
System.out.println(s2.equals(s3));//false
//s1和s4值相同,但是不是同一个对象,地址不同
System.out.println(s1.equals(s4));//false
}
}
equals()方法覆盖步骤:
- 比较两个引用是否指向同一个对象
- 判断obj是否为null
- 判断两个引用指向的实际对象类型是否一致
- 强制类型转换
- 一次比较各个属性值是否相同
package com.yushuo.object.demo04;
public class Student {
private String name;
private int age;
//无参构造器
public Student() {
}
//有参构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.yushuo.object.demo04;
public class Application {
public static void main(String[] args) {
//equals()方法,判断两个对象是否相等,即地址是否相同
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
Student s3 = s1;
Student s4 = new Student("张三",20);
System.out.println(s1.equals(s2));//false
System.out.println(s1.equals(s3));//true
System.out.println(s2.equals(s3));//false
//s1和s4值相同,但是不是同一个对象,地址不同
System.out.println(s1.equals(s4));//false
}
}
finalize()方法
- 当对象被判定为垃圾对象时,有JVM自动调用此方法,用以标记垃圾对象,进入回收队列
- 垃圾对象:没有有效引用指向此对象时,为垃圾对象
- 垃圾回收:有GC销毁垃圾对象,是否数据存储空间
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
- 手动回收机制:使用System.gc(); 通知JVM执行垃圾回收,具体JVM会不会回收看具体情况
package com.yushuo.object.demo05;
public class Student {
private String name;
private int age;
//无参构造器
public Student() {
}
//有参构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
protected void finalize() throws Throwable {
System.out.println(this.name + "对象被回收了");
}
}
package com.yushuo.object.demo05;
public class Application {
public static void main(String[] args) {
Student s1 = new Student("张三",21);
Student s2 = new Student("李四",22);
Student s3 = new Student("王五",23);
new Student("赵六",24);
new Student("顾七",25);
//回收垃圾
System.gc();
System.out.println("回收垃圾");
/**
* 输出结果
* 回收垃圾
* 顾七对象被回收了
* 赵六对象被回收了
*/
}
}
包装类
包装类概念
- 基本数据类型所对应的引用数据类型
- Object可同意所有数据,包装类的默认值是null
- 包装类对应:
- byte——Byte
- short——Short
- int——Integer
- long——Long
- float——Float
- double——Double
- boolean——Boolean
- char——Character
装箱和拆箱
基本类型变量村存储再栈内,引用类型存储再堆内,栈中有引用
装箱:栈内的数据转移到堆内,基本类型转换为引用类型
拆箱:堆内的对象转移到栈内,引用类型转换为基本类型
-
8种包装类提供不同类型见的转换方式
-
Number父类种提供的6个共性方法
package com.yushuo.packaging; public class Demo01 { public static void main(String[] args) { //类型转换:装箱,基本类型转成引用类型的过程 //基本类型 int num1 = 18; int num2 = 20; //使用Integer类创建对象,两种方式 Integer integer1 = new Integer(num1); Integer integer2 = Integer.valueOf(num2); //类型转换:拆箱,引用类型转换为基本类型的过程 Integer integer3 = new Integer(100); int num3 = integer3.intValue(); //JDK1.5之后,java提供自动装箱和拆箱 //反编译之后其实也和上面的一样 //自动装箱,相当于valueOf Integer integer4 = num1; //上面等价于Integer integer4 = Integer.valueOf(num1); //自动拆箱 int num4 = integer4; } }
-
parseXXX()静态方法
package com.yushuo.packaging; public class Demo02 { public static void main(String[] args) { //基本类型和字符串之间转换 //基本类型转换为字符串 int num1 = 100; //方法1:使用+号 String s1 = num1 + ""; //方法2:使用Integer中的toString()方法 String s2 = Integer.toString(num1); //以16进制转换 String s3 = Integer.toString(num1,16); System.out.println(s1);//100 System.out.println(s2);//100 System.out.println(s3);//64 //字符串转换为基本类型 String str1 = "100"; //使用Integer.parseXXX()方法 //使用Integer.parseInt()方法,str里面不能有非整数的 int num2 = Integer.parseInt(str1); //将16进制的str转换为10进制的数字 int num3 = Integer.parseInt("64",16); System.out.println(num2);//100 System.out.println(num3);//100 //boolean类型字符串形式转化为基本类型 //“true”-->true、非“true”-->false String str2 = "true"; String str3 = "fawfasd"; boolean b1 = Boolean.parseBoolean(str2); boolean b2 = Boolean.parseBoolean(str3); System.out.println(b1);//true System.out.println(b2);//false } }
-
valueOf()静态方法
之前已经用过。
-
-
注意:需保证类型兼容,否则抛出NumberFormatException异常
整数缓冲区
-
Java预先创建了256个常用的整数包装类型对象,范围-128到127
如果将int转换为Integer时,范围再整数缓冲区之内,则返回的是已经创建好的Integer对象,如果超出范围,就是新建的对象。
-
在实际应用当中,对已创建的对象进行复用,可以减少内存消耗
package com.yushuo.packaging;
public class Demo03 {
public static void main(String[] args) {
//面试题
/**
* integer1和integer2,二者new的不同
* 二者内容虽然相同,但是存储再不同地址
* 地址不同,因此二者不相等
*/
Integer integer1 = new Integer(100);
Integer integer2 = new Integer(100);
System.out.println(integer1 == integer2);//false
/**
* 对于自动装箱
*整数缓冲区,范围为-128到127
* 如果在此范围内,会直接返回已经预创建的对象
* 如果不在此范围内,而是创建新的对象,即new Integer
* integer3和integer4,都是预创建的,因此相同
* integer5和integer6,都是新创建的,因此不同
*/
Integer integer3 = 100;
Integer integer4 = 100;
Integer integer5 = 200;
Integer integer6 = 200;
System.out.println(integer3 == integer4);//true
System.out.println(integer5 == integer6);//false
}
}
String类
String概述
-
字符串是常量,创建之后不可改变
-
字符串字面值存储在字符串池中,可以共享
(JDK8以前,字符串池在方法区,8及以后在堆中)
package com.yushuo.string; public class Demo01 { public static void main(String[] args) { //"hello"常量,存储在字符串池中 String name1 = "张三"; /** * 将"李四"赋值给name,并没有改变”hello“ * 实际上在字符串池新开辟了一个空间,存储”李四“ * 将栈内的name改而指向”李四“ */ name1 = "李四"; /** * 再创建一个字符串变量name2,令其等于“张三” * 实际过程,在字符串池中寻找"张三" * 如果有,将栈内的name2指向"张三" * 如果没有找到,则开辟新的空间 */ String name2 = "张三"; } }
-
字符串变量创建方法:
- String s = “Hello”; 产生一个对象,字符串池中存储
- String s = new String(“Hello”); 产生两个对象,堆、池各一个
package com.yushuo.string; public class Demo02 { public static void main(String[] args) { /** * 字符串变量创建方式1 * 先在字符串池中寻找“Hello” * 如果找到,直接将栈中的s1指向字符串池中的“Hello” * 如果没有找到,在字符串池中新开辟一个空间,存储"Hello",然后变量指向它 */ String s1 = "Hello"; String s2 = "Hello"; System.out.println(s1 == s2);//true /** * 字符串变量创建方式2:new String * 在字符串池中开辟一个空间,存储"Hello" * 在堆中开辟一个空间,存储"Hello" * 栈中的s3指向堆中的地址 * 实际运行时,堆中没有"Hello",而是指向字符串池中的"Hello" */ String s3 = new String("Hello"); String s4 = new String("Hello"); System.out.println(s3 == s4);//false,比的是地址 System.out.println(s3.equals(s4));//true,比的是内容 } }
String常用方法
- public int length():返回字符串的长度
- public char charAt(int index):根据下标获取字母
- public boolean contains(String str):判断当前字符串中是否包含str
package com.yushuo.string;
public class Demo03 {
public static void main(String[] args) {
/**
* 字符串方法的使用
* length();返回字符串的长度
* charAt(int index);返回某个位置的字符
* contains(String str);判断是否包含某个字符串
*/
String content = "张三和李四一起出游";
System.out.println(content);//张三和李四一起出游
System.out.println(content.length());//9
//字符串角标0到length()-1
System.out.println(content.charAt(8));//游
System.out.println(content.contains("你好"));//false
System.out.println(content.contains("一起"));//true
}
}
- public char[] toCharArray():将字符串转换成数组
- public int indexOf(String str):查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1
- public int lastIndexOf(String str):查找字符串在当前字符串中最后一次出现的下标索引
package com.yushuo.string;
import java.util.Arrays;
public class Demo04 {
public static void main(String[] args) {
/**
* 字符串方法的使用
* toCharArray();返回字符串对应的数组
* indexOf(String str);返回子字符串首次出现的位置
* lastIndexOf(String str);返回子字符串最后一次出现的位置
*/
String content = "张三,zhangsan,和李四,lisi,一起,lisi,出游";
System.out.println(Arrays.toString(content.toCharArray()));
//[张, 三, ,, z, h, a, n, g, s, a, n, ,, 和, 李, 四, ,, l, i, s, i, ,, 一, 起, ,, l, i, s, i, ,, 出, 游]
System.out.println(content.indexOf("lisi"));//16
//从第18个字符开始找
System.out.println(content.indexOf("lisi",18));//24
System.out.println(content.lastIndexOf("lisi"));//24
}
}
- public String trim():去掉字符串前后的空格
- public String toUpperCase():将小写转成大写
- public boolean endWith(String str):判断字符串是否以str结尾
package com.yushuo.string;
import java.util.Locale;
public class Demo05 {
public static void main(String[] args) {
/**
* 字符串方法的使用
* trim();去掉字符串前后的空格
* toUpperCase();把小写转成大写
* toLowerCase();把大写转成小写
* endsWith(str);判断是否以str结尾
* startsWith(str);判断是否以str开头
*/
String content2 = " hello ";
System.out.println(content2.trim());//hello
String content3 = "hello,WORLD";
System.out.println(content3.toUpperCase(Locale.ROOT));//HELLO,WORLD
System.out.println(content3.toLowerCase(Locale.ROOT));//hello,world
System.out.println(content3.endsWith("hello"));//false
System.out.println(content3.endsWith("WORLD"));//true
System.out.println(content3.startsWith("hello"));//true
System.out.println(content3.startsWith("WORLD"));//false
}
}
- public String replace(char oldChar, char newChar):将旧字符转换为新字符
- public String[] split(String str):根据str做拆分
package com.yushuo.string;
public class Demo06 {
public static void main(String[] args) {
/**
* 字符串方法的使用
* replace(char old,char new);用新的字符或字符串替换旧的字符或字符串
* split();对字符串进行拆分
*/
String content1 = "张三,zhangsan,和李四,lisi,一起,lisi,出游";
String content2 = "hello,WORLD";
System.out.println(content2.replace("WORLD", "world"));//hello,world
String[] arr = content1.split(",");
/**
* 两个字符
* String[] arr = content1.split("[ ,]");
* 即” “和","二者都使用,以将字符串拆分
* String[] arr = content1.split("[ ,]+");
* " "和","可以连续出现多个
*/
System.out.println(arr.length);//7
for (String s : arr) {
System.out.println(s);
}
/*
张三
zhangsan
和李四
lisi
一起
lisi
出游
*/
}
}
- 补充方法:equals和compareTo
package com.yushuo.string;
public class Demo07 {
public static void main(String[] args) {
/**
* 两个补充方法
* equals 判断是否相等
* compareTo();比较大小,根据编码表位置
*/
String s1 = "hello";
String s2 = "HELLO";
System.out.println(s1.equals(s2));//false
//忽略大小写判断
System.out.println(s1.equalsIgnoreCase(s2));//true
String s3 = "abc";
String s4 = "xyz";
/**
* 比较过程,从双方第一个字母开始,一个个比较
* 第一个相同,则比较第二个
* 出现第一个不同的,比较这两个的大小,为比较结果
* 如果一个长一个短,其余都一样,比较的就是长度
*/
System.out.println(s3.compareTo(s4));//s3-s4
//忽略大小写
System.out.println(s3.compareToIgnoreCase(s4));
}
}
String案例
需求:已知String str = “this is a text”;
- 将str中的单词单独获取出来
- 将str中的text替换为practice
- 在text前面插入一个easy
- 将每个单词首字母改为大写
package com.yushuo.string;
public class Demo08 {
public static void main(String[] args) {
/**
* 需求:已知String str = "this is a text";
* 1. 将str中的单词单独获取出来
* 2. 将str中的text替换为practice
* 3. 在text前面插入一个easy
* 4. 将每个单词首字母改为大写
*/
String str = "this is a text";
//将str中的单词单独获取出来
String[] arr = str.split(" ");
for (String s : arr) {
System.out.println(s);
}
//将str中的text替换为practice
String str1 = str.replace("text","practice");
System.out.println(str1);
//在text前面插入一个easy
//方法1:
String str2 = str.replace("text","easy text");
System.out.println(str2);
//方法2:使用StringBuffer
StringBuffer stringBuffer = new StringBuffer(str);
//stringBuffer.insert(9,"easy ")插入,在位置9插入字符串
//stringBuffer.toString()将StringBuffer转换为String
String str3 = stringBuffer.insert(str.indexOf("text"),"easy ").toString();
System.out.println(str3);
//将每个单词首字母改为大写
String str4= arr[0];
//或者String str4 = new String();
for (int i = 0; i < arr.length; i++) {
//获取每个单词第一个字母
char firstChar = str.charAt(str.indexOf(arr[i]));
//把小写字母转换为大写字母
char upperFirstChar = Character.toUpperCase(firstChar);
//arr[i].substring(1);截取字符串arr[i],可定义起始截取位置和终止截取位置
//将转换后的首字母与剩下单词拼接,并将所有单词拼接
if (i == 0){
str4 = upperFirstChar + arr[i].substring(1);
} else {
str4 = str4 + " " + upperFirstChar + arr[i].substring(1);
}
}
System.out.println(str4);
}
}
可变字符串
- StringBuffer:可变长字符串,JDK1.0提供,运行效率慢、线程安全
- StringBuilder:可变长字符串,JDK5.0提供,运行效率快、线程不安全
package com.yushuo.string;
public class Demo09 {
public static void main(String[] args) {
/**
* StringBuffer和StringBuilder的使用
* StringBuffer与StringBuilder方法基本相同
* 单线程时推荐使用StringBuffer
* 和String的区别:
* 效率比String高
* 比String节省内存
*/
StringBuffer stringBuffer = new StringBuffer();
//方法1:append();追加
stringBuffer.append("张三你好。");
//stringBuffer.toString()将StringBuffer转换为String
System.out.println(stringBuffer.toString());//张三你好。
stringBuffer.append("李四你好。");
System.out.println(stringBuffer.toString());//张三你好。李四你好。
//方法2:insert();插入,可以指定位置插入
stringBuffer.insert(0,"大家好。");
System.out.println(stringBuffer.toString());//大家好。张三你好。李四你好。
//方法3:replace();替换,指定位置替换,把start到end-1的内容替换掉
stringBuffer.replace(0,3,"Hello");
System.out.println(stringBuffer.toString());//Hello。张三你好。李四你好。
//方法4:delete();删除,指定位置删除,删除范围start到end-1
stringBuffer.delete(0,6);
System.out.println(stringBuffer.toString());//张三你好。李四你好。
//清空
stringBuffer.delete(0,stringBuffer.length());
System.out.println(stringBuffer.toString());//无输出
System.out.println(stringBuffer.length());//0
}
}
package com.yushuo.string;
public class Demo10 {
public static void main(String[] args) {
//验证StringBuilder效率比String高
//开始时间
long start1 = System.currentTimeMillis();
String str = " ";
//字符串拼接
for (int i = 0; i < 99999; i++) {
str = str + i;
}
//结束时间
long end1 = System.currentTimeMillis();
System.out.println("String用时:" + (end1 - start1));//35719
long start2 = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 99999; i++) {
stringBuilder.append(i);
}
long end2 = System.currentTimeMillis();
System.out.println("StringBuilder用时:" + (end2 - start2));//2
}
}
BigDecimal类
package com.yushuo.bigDecimal;
public class Demo01 {
public static void main(String[] args) {
//面试题:
//原因:double的存储机制,存储的是近似值,因此经过运算,容易出现误差
double d1 = 1.0;
double d2 = 0.9;
System.out.println(d1 - d2);
//输出为:0.09999999999999998,不是0.1
double d3 = (1.4 - 0.5) / 0.9;
System.out.println(d3);
//输出为:0.9999999999999999,不是1
}
}
double类型存储机制:近似存储,存储的是近似值,因此在运算时容易出现误差。很多实际应用中需要精确运算,double不符合要求,需要借助BigDecimal
BigDecimal
-
位置:java.math包中
-
作用:精确计算浮点数
-
创建方式:BigDecimal bd = new BigDecimal(“1.0”);
-
方法:
-
减法运算bd1.subtract(bd2);为bd1-bd2
-
加法运算bd1.add(bd2);为bd1+bd2
-
乘法运算bd1.multiply(bd2);为bd1*bd2
-
除法bd1.divide(bd2);为bd1/bd2
除法除不尽时,需要指定保留几位小数以及模式
divide(BigDecimal bd, int scal, RoundingMode mode);
通常四舍五入,BigDecimal.ROUND_HALF_UP
-
package com.yushuo.bigDecimal;
import java.math.BigDecimal;
public class Demo02 {
public static void main(String[] args) {
//BigDecimal,大的浮点数精确计算
//一定要用字符串!!!
BigDecimal bigDecimal1 = new BigDecimal("1.0");
BigDecimal bigDecimal2 = new BigDecimal("0.9");
//减法运算bd1.subtract(bd2);为bd1-bd2
BigDecimal bigDecimal3 = bigDecimal1.subtract(bigDecimal2);
System.out.println(bigDecimal3);//0.1
//加法运算bd1.add(bd2);为bd1+bd2
BigDecimal bigDecimal4 = bigDecimal1.add(bigDecimal2);
System.out.println(bigDecimal4);//1.9
//乘法运算bd1.multiply(bd2);为bd1*bd2
BigDecimal bigDecimal5 = bigDecimal1.multiply(bigDecimal2);
System.out.println(bigDecimal5);//0.90
//除法bd1.divide(bd2);为bd1/bd2
//(1.4-0.5)/0.9
BigDecimal bigDecimal6 = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
System.out.println(bigDecimal6);//1
//如果除不尽,需要指明保留几位小数
//保留3位,四舍五入
BigDecimal bigDecimal7 = new BigDecimal("10")
.divide(new BigDecimal("6"),3,BigDecimal.ROUND_HALF_DOWN);
System.out.println(bigDecimal7);//1.667
}
}
时间类型
Date类
-
Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法所取代
-
时间单位:
1秒 = 1000毫秒
1毫秒 = 1000微秒
1微妙 = 1000纳秒
package com.yushuo.time;
import java.util.Date;
public class Demo01 {
public static void main(String[] args) {
//Date类
//创建一个Date对象
//今天
Date date1 = new Date();
//两种时间显示格式
System.out.println(date1.toString());
System.out.println(date1.toLocaleString());
//昨天,即今天时间减去60*60*24*1000毫秒
Date date2 = new Date(date1.getTime() - 60*60*24*1000);
System.out.println(date2.toString());
System.out.println(date2.toLocaleString());
//方法:after和before,判断时间的前后
System.out.println(date1.after(date2));//今天在昨天之后,故true
System.out.println(date1.before(date2));//今天不在昨天之前,古false
//方法:compareTo,时间毫秒相减,判断正负,正为1,负为-1
System.out.println(date2.compareTo(date1));
//方法:equals两个时间是否相等
System.out.println(date1.equals(date2));
}
}
Calendar类
-
Calendar提供了获取或设置各种日历字段的方法
-
构造方法:
protected Calendar():由于修饰符时protected,所以无法直接创建该对象
-
其他方法
static Calendar getInstance() 使用默认时区和区域获取日历 方法名 说明 void set(int year,int month,int date,int hourOfDay,int minute,int second) 设置日历的年、月、日、时、分、秒 int get(int field) 返回给定日历字段的值。字段比如年、月、日等 void setTime(Date date) 用给定的Date设置此日历的时间。Date-Calendar Date getTime() 返回一个Date表示此日历的时间。Calendar-Date void add(int field,int amount) 按照日历的规则,给指定字段添加或减少时间量 long getTimeMillies() 毫秒为单位返回该日历的时间值
SimpleDateFormat类
-
SimpleDateFormat是一个以语言环境有关的方式来格式化和解析日期的具体类
-
进行格式化(日期->文本),解析(文本->日期)
-
常用的时间模式字母
字母 日期或时间 示例 y 年 2019 M 年中月份 5 d 月中天数 4 H 1天中小时数(0-23) 15 m 分钟 45 s 秒 23 S 毫秒 367
package com.yushuo.time;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo03 {
public static void main(String[] args) throws Exception{
//SimpleDateFormat类
//创建SimpleDateFormat对象,可以自己设置格式
//格式要求,年4位,月2位,日2位
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
//创建时间
Date date1 = new Date();
//格式化Date(把日期转成字符串)
String str = simpleDateFormat.format(date1);
System.out.println(str);
//解析(把字符串转成日期)
//如果不按格式输入会报错,因此方法需要加上抛出异常throws Exception
Date date2 = simpleDateFormat.parse("2021/03/22");
System.out.println(date2);
}
}
System类
-
System系统类,主要用于获取系统的属性数据和其他操作,构造方法私有
方法名 说明 static void arraycopy(…) 复制数组 static long currentTimeMillis() 获取当前系统时间,返回的是毫秒值 static void gc() 建议JVM赶快启动垃圾回收器回收垃圾 static void exit(int status) 退出JVM,如果参数是0表示正常退出JVM,非0表示异常退出JVM
package com.yushuo.time;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
protected void finalize() throws Throwable {
System.out.println("回收了" + name + "对象");
}
}
package com.yushuo.time;
import java.lang.reflect.Array;
import java.util.Arrays;
public class Demo04 {
public static void main(String[] args) {
//System系统类
/**
* arraycopy(src,srcPoS,dest,destPos,length),数组的复制
* src:源数组
* srcPoS:从哪个位置开始复制
* dest:目标数组
* destPos:目标数组的位置
* length:复制的长度
* Arrays.copyOf用的就是arraycopy
*/
int[] arr1 = {1,2,3,4,5,6,7,8};
int[] arr2 = {2,3,4,5,6,7,8,9};
System.arraycopy(arr1,5,arr2,3,2);
//打印数组,方式1
for (int i : arr2) {
System.out.println(i);
}
//打印数组,方式2
System.out.println(Arrays.toString(arr2));
//currentTimeMillis,显示时间,可以用来计时
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < 999999999; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("用时:" + (end - start) + "毫秒");
//gc,告诉垃圾回收器回收垃圾,具体是否回收看实际情况
Student student1 = new Student("张三",16);
Student student2 = new Student("李四",16);
Student student3 = new Student("王五",16);
new Student("赵六",16);
new Student("顾七",16);
new Student("唐八",16);
System.gc();
//exit,退出JVM
System.exit(0);
System.out.println("hello");//不会输出,因为前一行已经退出了JVM
}
}
总结
- 内部类:
- 在一个类的内部再定义一个完整的类
- 成员内部类、静态内部类、局部内部类、匿名内部类
- Object类:
- 所有类的直接或间接父类,可存储任何对象
- 包装类:
- 基本数据类型所对应的引用数据类型,可以使用Object统一所有数据
- String类:
- 字符串是常量,创建之后不可改变,字面值保存在字符串池中,可以共享
- BigDecimal类:
- 可精确计算浮点数
- Date:
- 特定时间
- Calendar类:
- 日历
- SimpleDateFormat类:
- 格式化时间
- System类:
- 系统类