java常用类相关内容
1.内部类
概念
- 在一个类的内部在定义一个完整的类
特点
- 编译之后可生成独立的字节码文件
- Outer.class && Outer$Inner.class
- 内部类可直接访问外部类的私有成员,而不破坏封装
- 可为外部类提供必要的内部功能组件
/**
* 内部类四种形式:
* 1 成员内部类
* 2 静态内部类
* 3 局部内部类
* 4 匿名内部类
*/
public class Outer {
private String name;
//内部类:一个类中包含一个完整的类,里层的类称为内部类,外层类称为外部类
class Inner{
}
}
分类
成员内部类
- 在类的内部定义、与实例变量、实例方法同一级别
- 创建成员内部类对象要依赖外部类对象
- Outer out = new Outer();
- Inner in = out.new Inner();
- 二合一 new Outer().new Inner();
- 特点
- 成员内部类可以使用任何访问修饰符
- 因为成员内部类与实例属性、实例方法同级别
- 外部类只能用public和默认的
- 成员内部类可直接访问外部类的属性和方法
- 因为成员内部类与实例方法同级别
- 当外部类与内部类存在重名属性时,会优先访问内部类属性,使用“外部类名.this”访问外部类的属性
- 成员内部类不能定义静态成员(属性和方法)
- 在类加载的时候,static变量就会被初始化,那么我们Inner对象在没有Outer这个对象的时候便生成了。这样这个成员内部类就脱离了外部类的掌控,不需要外部类的对象就可以生成内部类的对象,这与成员内部类的定义就相驳了,因为我们知道成员内部类的对象必须是现有外部类的对象才能创建,并且是绑定在一起的,所以成员内部类不可以定义静态变量。
- 成员内部类是和实例方法同级别
- 在加载Outer外部类的时候,内部类的静态属性就会被初始化,这是不被允许的,因为内部类没有new对象
- 成员内部类可以包含静态常量
- static final 特殊不可改变
- 在外部类加载的时候就已经赋值,将值替换成初始值,不可改变。加载一次,定义了也没有关系
- 成员内部类可以使用任何访问修饰符
public class Outer {
//实例属性
private String name="张三";
private int age=20;
//实例方法
public void show(){
System.out.println(name+"...."+age);
}
//成员内部类:在类的内部定义,与实例变量、实例方法同级别的类。
//特点:
/*
1成员内部类可以使用任意访问修饰符。
2成员内部类可以直接访问外部类的属性和方法。
3成员内部类中属性和外部类的属性同名时,使用"外部类名.this"访问外部类的属性
4成员内部类不能包含静态成员,但是可以包含静态常量。*/
class Inner{
private String phone="1316737137";
private String address="北京";
private String name="灿灿";
public void show(){
System.out.println(phone+"..."+address);
System.out.println(this.name+"======="+Outer.this.age);
System.out.println(Outer.this.name+"======="+Outer.this.age);
}
}
}
public class Test {
public static void main(String[] args) {
//1 创建外部类对象
/*
Outer outer=new Outer();
outer.show();
//2 创建内部类对象
Outer.Inner inner=outer.new Inner();
inner.show();
*/
//合二为一
Outer.Inner inner2 = new Outer().new Inner();
inner2.show();
}
}
[wppay]
静态内部类
- static修饰的成员内部类
- 不依赖外部类对象,可直接创建或通过类名访问,相当于外部类(Outer),为外部类提供功能
- 学校类里面有一个保安类,保安类可以拿出来,但是放在学校类里面表示只属于这一个学校
- 特点
- 可以使用任意访问修饰符
- 不能直接访问外部类的实例属性和方法需要实例化外部类对象,可直接访问外部类的静态属性和方法
- 可包含静态成员(静态的属性和方法)
public class Outer {
private String name = "李四";
private int age = 18;
public void show() {
System.out.println(name + "..." + age);
}
private static int count = 10000;
//静态内部类:不依赖外部类对象,可直接创建或通过类名访问,相当于外部类,为外部类提供功能。
//特点
/**
* 1静态内部类可以使用任意访问修饰符。
* * 2静态内部类不能直接访问外部类的实例属性和方法,可以直接访问静态的属性和方法。
* * 3静态内部类可以包含静态成员。
*/
static class Inner {
private String phone = "110";
private String email = "lisi@qq.com";
public void show() {
System.out.println(phone + "..." + email);
Outer outer = new Outer();
System.out.println(outer.name + "..." + outer.age);
System.out.println(Outer.count);
}
public static void haha() {
}
}
}
import com.fq.lz.Day12.day12_2.Outer.Inner;
public class Test {
public static void main(String[] args) {
//直接创建静态内部类对象
Inner inner=new Inner();
inner.show();
}
}
局部内部类
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
特点:
- 不能使用任何访问修饰符
- 和局部变量同一级别
- 如果局部内部类所在方法是实例方法,可以直接访问外部类的实例属性和方法,如果局部类所在的方法是静态方法,不能访问
- 局部内部类访问上一层的外部类(实例方法)中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
- JDK1.8之后可以不写final,但不表示没有
- 为什么加final
- 局部内部类也不能声明静态成员(静态的属性和方法)、可以使用静态常量
public class Outer {
private String name = "龙哥";
private int age = 22;
public void show() {
//局部变量
final int num = 100;
//局部内部类:定义在外部类方法中,作用范围和创建对象范围仅限于当前方法,限制类的使用范围。
//特点:
//1 不能使用任何访问修饰符
//2 如果局部内部类所在方法是实例方法,可以直接访问外部类的实例属性和方法;如果局部内部类所在方法是静态方法,只能访问外部类的静态属性和方法。
//3 局部内部类可以访问局部变量,但是局部变量必须是final,JDK1.8 final可以省略 ,对象生命周期长于局部变量。
//4 局部内部类也不能声明静态成员, 可以使用静态常量
class Inner {
private String phone = "120";
private String email = "longge@qq.com";
public void innerShow() {
System.out.println(phone + "...." + email);
System.out.println(Outer.this.name + "...." + Outer.this.age);
System.out.println(num);
}
}
//使用局部内部类创建对象
Inner inner = new Inner();
inner.innerShow();
}
}
class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();
}
}
匿名内部类
没有类名的局部内部类,是对局部内部类的优化
- 一切特征都与局部内部类相同
- 使用匿名内部类优化局部内部类,实际创建接口实现类,眼看不见
- 从生成了class文件看
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
创建方式直接new接口、抽象类的对象
优点:减少代码量。缺点:可读性差
特点
- 创建匿名内部类可以使用接口、抽象类、普通类、必须实现接口和抽象类中抽象方法
- 不能手动添加构造方法
- 没有类名,构造方法要与类名一致。但是他有构造方法
- 不能包含静态成员
- 通过类名访问,无法访问
- 一般不包含特有方法、可以写但是不能直接访问
- 通过可访问方法(实现的方法)调用
- 匿名对象调用(见下图)
- 生成class文件名:外部类名$编号.class
Lambda表达式优化匿名内部类
方法引用优化Lambda表达式
interface Usb {
void service();
}
class Mouse implements Usb {
@Override
public void service() {
System.out.println("鼠标连接成功,开始工作...");
}
}
public class Test {
public static void main(String[] args) {
Usb usb=new Mouse();
usb.service();
//局部内部类,实现接口
class Upan implements Usb{
@Override
public void service() {
System.out.println("Upan连接成功,开始工作...");
}
}
Usb usb2=new Upan();
usb2.service();
//使用匿名内部类优化局部内部类, 实际创建Usb接口实现类对象。
//特点:
//1创建匿名内部类可以使用接口,抽象类,普通类,必须实现接口或抽象类中抽象方法。
//2匿名内部类不能手动添加构造方法, 不能包含静态成员。
//3匿名内部类中一般不包含特有的方法,不能直接访问,可以通过可访问方法调用或匿名对象调用。
//4匿名内部类生成的class文件名:外部类名$编号.class
Usb usb3=new Usb(){
@Override
public void service() {
System.out.println("风扇连接成功,开始工作...");
}
};
usb3.service();
//Lambda表达式优化匿名内部类
Usb usb4=()->System.out.println("硬盘连接成功,开始工作...");
usb4.service();
//方法引用优化Lambda表达式
}
}
2.Object类
概念
- 超类、基类、所有类的直接或间接父类,位于继承树的最顶层
- 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
- 可以作为参数和返回值
Object类中所定义的方法
- getClass()方法
- 每个类加载到内存后都有一个类对象,返回引用中存储的实际对象类型
- 判断两个引用中实际存储对象类型是否一致
- hashCode()方法
- 返回该对象的十进制的哈希值 - 理解为对象的地址
- 根据对象的地址或字符串或数组计算出int类型数值
- 根据对象的地址或字符串或数组计算出int类型数值
- toString()方法
- 返回对象的字符串表示
- 默认返回 类名@十六进制哈希值:getClass().getName() + "@" + Integer.toHexString(hashCode()
- 可以根据需求重写该方法,返回对象各个属性
- 直接打印对象,相当于对象调用了toString()
- 返回对象的字符串表示
- equals()方法
- 默认实现为(this==obj),比较两个对象的地址
- 基本数据类型比较值
- 引用数据类型比较地址
- 可以重写equals()方法比较属性是否相等
- 1.判断obj是否为空
- 2.判断是否是同一个对象
- 3.判断obj是否是Student类创建的对象
- 4.比较-向下转型比较属性
- 快捷键重写
- 默认实现为(this==obj),比较两个对象的地址
- finalize()方法
- 什么样的对象是垃圾对象:没有任何引用的对象
- 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间
- JDK1.9之后不建议重写
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
- 手动回收机制:使用System.gc():通知JVM执行垃圾回收
面试题:equals和==的区别
- equals()是Object中提供的,比较的是地址
- ==是java运算符,如果是基本类型比较的是值,如果是引用类型比较的是地址
- 默认Object中的equals()方式的实现与==相同,代码如下:return this==obj
- 可以在类中重写equals()方法满足特定的需求
字符串的比较用equals()方法,重写了equals方法,比较的是字符数组
public class TestObject {
public static void main(String[] args) {
//testGetClass();
//testHashCode();
//testToString();
//testEquals();
testFinalize();
}
//getClass()方法的使用:返回类对象
public static void testGetClass() {
Student s1 = new Student("灿灿", 20);
Student s2 = new Student("龙哥", 22);
System.out.println(s1.getClass());
System.out.println(s2.getClass());
System.out.println(s1.getClass() == s2.getClass());
if (s1 instanceof Student && s2 instanceof Student) {
System.out.println(true);
}
}
//hashCode()方法的使用:返回对象的哈希值(理解为对象的地址)
public static void testHashCode() {
Student s1 = new Student("灿灿", 20);
Student s2 = new Student("龙哥", 22);
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}
//toString()方法的使用:返回对象的字符串形式
public static void testToString() {
Student s1 = new Student("灿灿", 20);
Student s2 = new Student("龙哥", 22);
System.out.println(s1.toString());
System.out.println(s2.toString());
System.out.println(s1);//相当于调用toString();
System.out.println(s2);//相当于调用toString();
}
//equals()方法的使用:比较两个对象
//面试题:equals和==的区别?
//(1)equals()是Object中提供的方法;==是java种一个运算符,如果是基本类型比的值,引用类比较的是地址。
//(2)默认Object中的equals方法和 ==一样,代码如下:return this==obj;
//(3)可以在自定义类中重写equals方法,满足特定的需求。
public static void testEquals() {
Student s1 = new Student("灿灿", 20);
Student s2 = new Student("灿灿", 20);
boolean b1 = s1.equals(s1);
boolean b2 = s1 == s2;
System.out.println(b1);
System.out.println(b2);
}
//finalize()方法的使用: 完成,结束,垃圾回收器回收垃圾对象(没有任何引用的对象称为垃圾对象)之前执行
public static void testFinalize() {
Student s1 = new Student("灿灿1", 20);
Student s2 = new Student("灿灿2", 20);
Student s3 = new Student("灿灿3", 20);
Student s4 = new Student("灿灿4", 20);
Student s5 = new Student("灿灿5", 20);
s1 = null;
s2 = null;
s3 = null;
s4 = null;
s5 = null;
//手动告诉垃圾回收器回收垃圾
System.gc();//Garbage Collector
}
}
class Student extends Object {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
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
public boolean equals(Object obj) {
//1 判断obj是否为空
if (obj == null) {
return false;
}
//2 判断是否是同一个对象
if (this == obj) {
return true;
}
//3判断obj是否是Student
if (obj instanceof Student) {
//4 向下转型
Student s = (Student) obj;
//5 比较姓名和年龄
if (this.name.equals(s.name) && this.age == s.age) {
return true;
}
}
return false;
}
//JDK1.9之后不建议重写
@Override
protected void finalize() throws Throwable {
System.out.println(this.name + "..." + this.age + " 被回收了...");
}
}
3.包装类
基本数据类型对应的引用数据类型
为什么需要包装类?
- Object可统一所有数据,包装类默认值是null
- 基本类型功能比较弱
包含内容:
基本数据类型包装成包装类(装箱)
- 通过包装类的构造器实现
- int i = 500;Integer t = new lnteger(i);
- 通过字符串参数构造包装类对象
- Float f = new Float("4.56");
- 类型不兼容抛出NumberFormatException
获得包装类对象中包装的基本类型变量(拆箱)
- 调用包装类的.xxxValue()方法
- boolean b = Object.booleanValue();
JDK1.5之后支持自动装箱,自动拆箱,类型必须匹配。
- 自动装箱
- int count = 1000; Integer a = count;
- 对应:Integer a =Integer.valueOf(count)
- 自动拆箱
- int count2 = a;
- 对应:int count2 = a.intValue();
- 如何实现自动装箱和自动拆箱
- Integer a =Integer.valueOf(count)
- int count2 = a.intValue();
- int n1 = 10; Integer a2 = n1; n1==a2的布尔值为true 自动拆箱
- n1 == n2.intValue()
- 面试题
整数的缓冲区:缓存数组的范围:-128~127
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
String与基本数据类型与包装类之间的转换:转换的时候可选择进制
字符串转成Boolean类型转换 非“false”或“true”->全是false
String d2 = "true";
boolean d3 = Boolean.parseBoolean(d2);
Double 比较存储近似值 不要用大于小于的方式
Double e1 = 3.14;
Double e2 = 3.139999;
//System.out.println(e1 == e2);
System.out.println(Double.compare(e1, e2));
测试代码:
public class Demo1 {
public static void main(String[] args) {
//(1)装箱:把基本类型转成包装类类型
System.out.println("-----装箱-------");
//基本类型
int age=20;
//创建包装类对象
Integer integer=new Integer(age);
System.out.println("age:"+age+" integer:"+integer.toString());
//(2)拆箱:把包装类类型转成基本类型转成基本类型
System.out.println("-----拆箱-------");
Integer integer2=new Integer(200);
int num=integer2.intValue();
System.out.println("integer2:"+integer2+" num:"+num);
//jdk1.5之后,Java支持自动装箱和拆箱
System.out.println("-----自动装箱------");
int count=1000;
//Integer integer3=count;
Integer integer3=Integer.valueOf(count);
System.out.println("count:"+count+" integer3:"+integer3);
System.out.println("-----自动拆箱------");
// int count2=integer3;
int count2=integer3.intValue();
System.out.println("integer3:"+integer3+"count2:"+count2);
System.out.println("-------------比较-----------------");
int n1=10;
Integer integer4=n1;
System.out.println(n1==integer4);//integer4自动拆箱
System.out.println("------------面试题---------------");
Integer integer5=Integer.valueOf(50);
Integer integer6=Integer.valueOf(50);
System.out.println(integer5==integer6);// true
Integer integer7=Integer.valueOf(200);
Integer integer8=Integer.valueOf(200);
System.out.println(integer7 ==integer8);//false
Integer integer9=new Integer(50);
Integer integer10=new Integer(50);
System.out.println(integer9==integer10);//false
//基本类型和字符串之间的转换
//1 基本类型转成字符串
System.out.println("------1 基本类型转成字符串------");
int num2=15;
String s=num2+"";
String s2=Integer.toString(num2, 16);
System.out.println(s);
System.out.println(s2);
//2 字符串转成基本类型
String s3="100";
System.out.println("------2 字符串转成基本类型------");
int num3=Integer.parseInt(s3,2);
System.out.println(num3);
//3 Boolean类型转换
String s4="haha"; //"true"--->true , 非"true" 全是false
boolean b=Boolean.parseBoolean(s4);
System.out.println(b);
//Double 比较
double d1=3.14;
double d2=3.1399999999999999;
Double.compare(d1, d2);
}
}
4.String
概念:
- 字符串是常量,创建以后不可改变
- 正常使用不可变,但可以使用反射技术来改变字符串中的数组
- 从JDK1.9开始底层实现用的是byte[]数组,之前用的是char[]数组
两种创建方式:
- String s = "asd";
- 字符串字面值存储在常量池中,可以共享
- JDK1.7之前字符串常量存放在方法区中的常量池
- JDK1.7之后移入堆中
- 方法区在JDK1.8之前也叫永久代,JDK1.8叫元空间
- 不可变性的理解
- 字符串字面值存储在常量池中,可以共享
相同字符串值的可重复引用
- String s = new String("asd");
在常量池中实际以数组的方式存储,返回的表示是一个字符串
产生几个对象的问题:
- String s = "hello"; 产生一个对象,在字符串池中存储
- 产生两个对象
- 相同字符串值的可重复引用
常用方法
- equals:比较两个字符串是否相等
- compareTo():比较字符串的大小,前面的在编码表里的位置,减去后面一个,返回值
- substring() 方法返回字符串的子字符串。
- substring(int beginIndex)
- substring(int beginIndex, int endIndex)
- 索引从 0 开始
- intern():保留
- 判断常量池中有没有,没有则把对象复制一份(或对象引用)放入常量池中,有返回常量池中的对象
- JDK1.7之前是复制一份放入常量池(方法区),JDK1.7之后则把对象引用复制到常量池(堆中)
String s3 = s1+s2;放在堆里面,String a3 = (new StringBuilder()).append(a1).append(a2).toString();
特例:特殊关键字已经在常量池里面有了
public class Demo4 {
//字符串中常见方法的使用
public static void main(String[] args) {
String s="java是世界上最好的语言,java第一,java真香";
//charAt();返回某个位置的字符
char first=s.charAt(0);
char last=s.charAt(s.length()-1);
System.out.println(first);
System.out.println(last);
//contains;判断字符串中是否包含参数
boolean b=s.contains("java");
System.out.println(b);
//toCharArray();返回字符数组
char[] chars = s.toCharArray();
System.out.println(Arrays.toString(chars));
//indexOf;返回参数字符串在字符串中第一次出现的位置
int pos=0;
while((pos=s.indexOf("java", pos))!=-1) {
System.out.println(pos);
pos += 4;
}
//lastIndexOf();返回最后一个位置
int posLast=s.lastIndexOf("java");
System.out.println(posLast);
//trim() ;去掉字符串前后的空格
String name=" zhang san ";
String name2=name.trim();
System.out.println(name);
System.out.println(name2);
//replace();替换
// " ":空格
// "" 空字符
String name3=name.trim().replace(" ", "");
System.out.println(name3);
//toUpperCase();把字符串转成大写
String s2=s.toUpperCase();
//s.toLowerCase();把字符串转成小写
System.out.println(s2);
//endsWith(String str);判断字符串是否以参数结尾
String filename="hello.java";
boolean b2=filename.endsWith(".java");
System.out.println(b2);
//startWith(String str)判断字符串是否以参数开头
boolean b3=filename.startsWith("hello");
System.out.println(b3);
//split(str);根据str做拆分。
String content="Java is the best language,java first.";
String[] arr=content.split("[ ,.]+");
System.out.println(arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
//substring();截取字符串,含头不含尾
String sub=s.substring(0, 4);
String lastsub=s.substring(s.length()-6);
System.out.println(sub);
System.out.println(lastsub);
//equals();比较两个字符是否相等
System.out.println("hello".equals("hello"));
//compareTo();比较两个字符串的大小。
// "abc" "xyz" 97 - 120 = -23
System.out.println("xyzabcd".compareTo("xyz"));
}
}
public class Demo8 {
public static void main(String[] args) {
//使用intern方法,把堆中字符串放入常量池。
// 1如果常量池中没有,则把对象复制一份(或对象引用)放入常量池中,并返回常量池中的对象
// 2如果常量池中存在,则直接返回。
//JDK1.7之前是复制一份放入常量池,JDK1.7之后则把对象引用到常量池。
// String s1="abc";
// String s2="xyz";
// String s5="abcxyz";
// String s3=s1+s2;
// String s4=s3.intern();
// System.out.println(s3==s4);
// System.out.println(s4==s5);
System.out.println("=========特殊 java void==========");
//java 、void
String s1="vo";
String s2="id";
String s3=s1+s2;
String s4=s3.intern();
System.out.println(s3==s4);
}
}
public class Demo2 {
public static void main(String[] args) throws Exception{
//字符串:不可变性:字符串变量赋值后,数据不可更改。变量可以重写赋值
String s1="hello";
s1="zhangsan";
String s3="hello";
System.out.println(s1);
//使用构造方法赋值
String name=new String("cancan");
//面试题1: String name=new String("cancan");在内存创建几个对象? 2个对象
//面试题2:写出一下结果
System.out.println("--面试题2:写出一下结果--");
String add="beijing";
String add2=new String(add);
System.out.println(add==add2);//false
System.out.println(add.equals(add2));//true
//验证add和add2是同一个数组
System.out.println("--验证add和add2是同一个数组--");
//获取value字段
Field field=add.getClass().getDeclaredField("value");
//访问权限无效
field.setAccessible(true);
//获取数组
char[] v= (char[]) field.get(add);
v[0]='B';
System.out.println(add2);
//字符串真的是不可变的吗? 正常使用是不可变的,但是可以反射技术来改变字符串中的数组。
}
}
public class Demo3 {
public static void main(String[] args) {
//面试题3:写出一下结果
String content1="hello";
String content2="world";
String content3="helloworld";
String content4=content1+content2;//堆
String content5="hello"+"world";
System.out.println(content3==content4);//false
System.out.println(content3.equals(content4));//true
System.out.println(content3==content5);//true
System.out.println(content3.equals(content5));//true
}
}
public class Demo5 {
//需求:已知String str = "this is a text";
//将str中的单词单独获取出来
//将str中的text替换为practice
//在text前面插入一个easy
//将每个单词的首字母改为大写
public static void main(String[] args) {
String str="this is a text";
//1 将str中的单词单独获取出来
String[] words=str.split(" ");
System.out.println(Arrays.toString(words));
//2将str中的text替换为practice
String str2=str.replace("text", "practice");
System.out.println(str2);
//3 在text前面插入一个easy
String str3=str.replace("text", "easy text");
System.out.println(str3);
//4 将每个单词的首字母改为大写
String str4="";
for (int i = 0; i < words.length; i++) {
String word=words[i];
char first=word.charAt(0);
char bigFirst=Character.toUpperCase(first);
String word2=bigFirst+word.substring(1);
str4+= word2+" ";
}
System.out.println(str4);
}
}
面试题
第一题:
验证值比较
第二题:
String content4 = (new StringBuilder()).append(c1).append(c2).toString();
String content5 = "helloworld";
可变字符串:StringBuilder和StringBuffer
不同于String,其对象必须使用构造器生成
可在内存中创建可变的缓冲空间,存储频繁改变的字符串
StringBuffer
- 可变长字符串,JDK1.0提供,运行效率慢,线程安全
StringBuilder
- 可变长字符串,JDK5.0提供,运行效率快,线程不安全
常用方法:append()、insert()、replace()、delete()
大量的字符串拼接一定要用StringBuilder或者StringBuffer
public class Demo6 {
//StringBuilder的使用
public static void main(String[] args) {
StringBuilder sb=new StringBuilder();
//StringBuffer sb=new StringBuffer();
//append();追加
sb.append("java是世界最好的语言");
System.out.println(sb.toString());
sb.append("java第一");
sb.append("我爱java");
System.out.println(sb.toString());
//insert();插入
sb.insert(0, "我爱北京");
System.out.println(sb.toString());
//replace();替换
sb.replace(0, 4, "helloworld");
System.out.println(sb.toString());
//delete();删除
sb.delete(0, 5);
System.out.println(sb.toString());
//清空
sb.delete(0, sb.length());
System.out.println("空:"+sb.toString());
}
}
public class Demo7 {
public static void main(String[] args) {
//获取从1970年0时0分0秒的毫秒数
long start = System.currentTimeMillis();
String s = "";
//StringBuilder s = new StringBuilder();
for (int i = 0; i <= 10; i++) {
//s = (new StringBuilder()).append(s).append(i).toString();
s += i;
//s.append(i);
}
//StringBuilder
System.out.println(s);
//String
System.out.println(s.toString());
long end = System.currentTimeMillis();
System.out.println(end - start);
//用时:
//String 19996
//StringBuilder 8
}
}
5.正则表达式
用字符串验证另一个字符串格式是否满足
https://github.com/ziishaned/learn-regex
用途:
- 匹配 str.matches(reg)
- 拆分 str.split(reg)
- 获取
- 1.编译为Pattern对象 Pattern p = Pattern.compile("[jJ]ava");
- 2.获取匹配器 Matcher matcher = p.matcher(str);
- 3.find();查找满足要求的字符串,找到返回true,没有找到返回false
- 替换 str.replaceAll("[Jj]ava", "php")
应用:
- 叠词替换 String hi="我..我..我喜喜….喜欢欢….欢JJJava";
- 去掉点 String hi2 = hi.replaceAll("[.]", "");
- 去掉重复的 String hi3 = hi2.replaceAll("(.)\1+", "$1");
语法:
public class Demo9 {
public static void main(String[] args) {
//Regular Expression
//1 匹配
//匹配手机号码
System.out.println("-----匹配--------");
String reg="1[3578][0-9]{9}";
String phone="13167371397";
boolean b=phone.matches(reg);
System.out.println(b);
//匹配QQ邮箱
String reg2="[1-9][0-9]{4,10}@[qQ]{2}\\.com";
String qq="113141@QQ.com";
boolean b2= qq.matches(reg2);
System.out.println(b2);
System.out.println("------拆分---------");
//2拆分
String str="Java is the best language,java first.";
String[] arr=str.split("[ .,]+");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("-------获取-------");
//3获取(了解)
//编译为Pattern对象
Pattern p=Pattern.compile("[jJ]ava");
//获取匹配器
Matcher matcher=p.matcher(str);
//find();查找满足要求的字符串,找到返回true,没有找到返回false
while(matcher.find()){
//group()获取满足的数据
System.out.println(matcher.group());
}
//4替换
System.out.println("---替换----");
String str2=str.replaceAll("[Jj]ava", "php");
System.out.println(str2);
//了解 叠词替换 String hi="我..我..我喜喜....喜欢欢....欢JJJava"; //我喜欢java
String hi="我..我..我我我喜喜....喜欢欢....欢JJJava"; //我喜欢java
//1 去掉.
String hi2=hi.replaceAll("[.]", "");
//2 去掉重复的
String hi3=hi2.replaceAll("(.)\\1+", "$1");
// char[] chars=new char[hi2.length()];
// chars[0]=hi2.charAt(0);
// int size=1;
// for(int i=1;i<hi2.length();i++){
// char c1=hi2.charAt(i);
// char c2=hi2.charAt(i-1);
// //判断chars数组中是否包含符号
// if(c1!=c2){
// //放进去
// chars[size++]=c1;
// }
// }
// String hi3=new String(chars, 0, size);
System.out.println(hi3);
}
}
6.BigDecimal类
实现精确计算浮点数 java.math包中
public class Demo1 {
//BigDecimal的使用:大数字类,作用:实现精确计算
public static void main(String[] args) {
//要写字符串,不然可能有误差
BigDecimal bd1=new BigDecimal("1.0");
BigDecimal bd2=new BigDecimal("0.9");
//加 不写toString 默认调用
BigDecimal result= bd1.add(bd2);
System.out.println(result.toString());
//减
BigDecimal result2=bd1.subtract(bd2);
System.out.println(result2);
//乘
BigDecimal result3=bd1.multiply(bd2);
System.out.println(result3);
//除
BigDecimal bd3=new BigDecimal("5");
BigDecimal bd4=new BigDecimal("3");
//HALF_UP四舍五入 HALF_DOWN五舍六入 除不尽报异常,没有指定保留的位数
BigDecimal result4=bd3.divide(bd4,2, RoundingMode.HALF_UP);
System.out.println(result4);
//BigInteger: 大整数类:实现精确计算,做大的数字的计算
BigInteger bi1=new BigInteger("111111111111111111111111111111");
BigInteger bi2=new BigInteger("222222222222222222222222222222");
BigInteger bi3=bi1.add(bi2);
System.out.println(bi3);
}
}
7.BigInteger类
大整数类,实现精确计算
8.Math类
public class Demo2 {
//Math的使用
public static void main(String[] args) {
//1绝对值
System.out.println(Math.abs(100));
System.out.println(Math.abs(-20));
//2 求立方根cbrt(double a)
System.out.println(Math.cbrt(27));
//3 ceil(double a) 返回大于或等于a的最小整数
System.out.println(Math.ceil(3.5));
System.out.println(Math.ceil(4));
//4 floor(double a) 返回小于或等于a的最大整数
System.out.println(Math.floor(3.5));
//5pow(double a, double b) 求次幂
System.out.println(Math.pow(2, 10));
//5random() 返回0到1之间的小数,含0不含1
System.out.println(Math.random());
//求0-9之间的整数
System.out.println((int)(Math.random()*10));
//求50-99之间的整数
System.out.println((int)(Math.random()*50)+50);
//求100-999
System.out.println((int)(Math.random()*900)+100);
//求15-30
System.out.println((int)(Math.random()*16)+15); //(int)(Math.random*(b-a+1))+a
//6round();四舍五入取整
System.out.println(Math.round(3.4));
//3.1415926
//四种实现四舍五入的方法
//Math.round 实现保留小数位数
System.out.println(Math.round(3.1455926*100)/100.0);
//pintf 实现保留小数位数
System.out.printf("%.2f",3.1415926);
System.out.println();
//BigDecimal 实现保留小数位数
BigDecimal bd=new BigDecimal("3.1455926");
BigDecimal bd2=bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(bd2);
//DecimalFormat:数字格式化类 #表示整数部分,0表示小数部分,一个0表示一个小数
DecimalFormat df=new DecimalFormat("#.00");
String s=df.format(3.1455926);
System.out.println(s);
}
}
保留小数位数:
- 四舍五入取整:Math.round(3.5) -> 4
- System.out.printf("%.2f",3.1415);
- BigDecimal
- DecimalFormat:数字格式化类
//数字格式化类,#表示整数部分,0表示小数部分有几位
DecimalFormat format = new DecimalFormat("#.00");
9.Random类
此类的实例用于生成伪随机数流
此类使用48位的种子,使用线性同余公式对其进行修改所得
若long种子确定,则在不同程序中,相同次数产生的随机数是相同的
public class Demo2 {
public static void main(String[] args) {
//Random类 有默认种子
Random random = new Random();
//nextInt 返回随机整数
int anInt = random.nextInt();
System.out.println(anInt);
//nextInt 返回指定范围的整数 0-99 [ )
int anInt1 = random.nextInt(100);
//nextDouble 返回0-1之间的小数,含0不含1
double aDouble = random.nextDouble();
//创建指定种子的随机数对象 种子一样生成的序列一样
Random random1 = new Random(1000);
Random random2 = new Random(1000);
for (int i = 0; i < 10; i++) {
System.out.println(random1.nextInt());
System.out.println(random2.nextInt());
}
}
}
10.Date类
表示瞬间,精确到毫秒,大部分方法失效,被Calender取代
时间单位:
- 1秒 = 1000毫秒
- 1毫秒 = 10000微秒
- 1微秒 = 1000纳秒
public class Demo4 {
public static void main(String[] args) {
//Date 表示瞬间,精确到毫秒
//现在
Date now=new Date();
System.out.println(now);
//昨天
Date yesterday=new Date(now.getTime()-60*60*24*1000);
System.out.println(yesterday);
//after,测试当前日期是否在指定日期之后
boolean b=now.after(yesterday);
System.out.println(b);
//before,测试当前日期是否在指定日期之前
boolean b2=now.before(yesterday);
System.out.println(b2);
//compareTo,比较两个时间的毫秒值,返回值是 1 0 -1
int r=now.compareTo(yesterday);
System.out.println(r);
//equals(Object obj)比较两个时间的毫秒值,如果毫秒值相等true,否则false
boolean b3=now.equals(yesterday);
System.out.println(b3);
Date tomorrow=new Date();
tomorrow.setTime(tomorrow.getTime()+60*60*24*1000);
//Wed Mar 17 11:21:57 CST 2021
System.out.println(tomorrow);
//2021-3-17 11:21:57
System.out.println(tomorrow.toLocaleString());
}
}
11.Calender类
public class Demo4 {
public static void main(String[] args) {
//Calender类的使用 特定的瞬间,精确到毫秒
//创建Calender对象
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH) + 1);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
System.out.println(calendar.get(Calendar.MINUTE));
System.out.println(calendar.get(Calendar.SECOND));
//创建昨天
Calendar yesterday = Calendar.getInstance();
yesterday.set(Calendar.DAY_OF_MONTH, 15);
//其他方法
//add方法
Calendar tommorrow = Calendar.getInstance();
tommorrow.add(Calendar.DAY_OF_MONTH, 1);
System.out.println(tommorrow.get(Calendar.DAY_OF_MONTH));
//获取精确的最大值
Calendar month1 = Calendar.getInstance();
month1.add(Calendar.MONTH, -1);
System.out.println(month1.getActualMaximum(Calendar.MONTH));
System.out.println(month1.getActualMinimum(Calendar.MONTH));
//获取可能最大值
System.out.println(month1.getMaximum(Calendar.DAY_OF_MONTH));
System.out.println(month1.getMaximum(Calendar.DAY_OF_MONTH));
//Calender和Date的转换
//data->Calender
Date date = new Date();
Calendar instance = Calendar.getInstance();
instance.setTime(date);
//Calender->data
Date time = instance.getTime();
}
}
12.SimpleDateFormat类
public class Demo6 {
//SimpleDateFormat:(1)格式化日期 (2)解析日期
public static void main(String[] args) throws Exception {
//(1)格式化日期
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String s=sdf.format(new Date());
System.out.println(s);
//(2)解析日期 日期格式不匹配的话报异常:ParseException(解析异常)
SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd");
String str="2020-10-1";
Date data2 = sdf2.parse(str);
System.out.println(data2);
}
}
13.System类
系统类,属性和方法都是共享的
public class Demo6 {
public static void main(String[] args) {
//System类:系统类,属性和方法都是共享的
//1.System.arraycopy
int[] ints = {1, 2, 3, 4, 5, 6, 7};
int[] ints1 = new int[ints.length * 2];
System.arraycopy(ints, 0, ints1, 0, ints.length);
for (int i = 0; i < ints.length; i++) {
System.out.print(ints1[i] + " ");
}
System.out.println();
//2.System.arraycopy()实现删除元素
System.arraycopy(ints, 1, ints, 0, ints.length - 1);
ints[ints.length - 1] = 0;
for (int i = 0; i < ints.length; i++) {
System.out.print(ints[i] + " ");
}
System.out.println();
//3.currentTimeMillis() 获取从1970年1月1日 到现在的毫秒值
//4.nanoTime() 返回最准确的可用系统计时器的当前值,以纳秒为单位
System.out.println(System.currentTimeMillis());
System.out.println(System.nanoTime());
//5.终止当前正在运行的JAVA虚拟机,0正常退出,非0非正常退出
//System.exit(0);
//System.out.println("测试执行");
//6.gc()告诉垃圾回收器回收垃圾
//System.gc();
//7.identityHashCode(Object x) 获取对象原始的HashCode
Name name = new Name();
System.out.println(name.hashCode());
System.out.println(System.identityHashCode(name));
String s = new String("hello");
String s2 = new String("hello");
//false
System.out.println(s == s2);
//重写了hashCode方法,返回相同
System.out.println(s.hashCode());
System.out.println(s2.hashCode());
//获取原始哈希值
System.out.println(System.identityHashCode(s));
System.out.println(System.identityHashCode(s2));
}
}
class Name {
String name;
@Override
public int hashCode() {
return 100;
}
}
14.Runtime类
每一个java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连。可以通过getRunntime方法获取当前运行时。
public class Demo8 {
//Runtime类的使用:运行时类,获取与当前系统有限的信息
public static void main(String[] args) throws Exception {
//获取运行时
Runtime runtime = Runtime.getRuntime();
//1 执行命令
//Process process=runtime.exec("notepad");
//Thread.sleep(3000);
//2关闭进程
//process.destroy();
//3 终止当前正在运行的java虚拟机
//runtime.exit(0);
//System.exit();
//4 建议JVM赶快启动垃圾回收器回收垃圾
//runtime.gc();
//System.gc();
//5 获取内存信息
//-Xmx:最大大小
//-Xms:初始大小
//-Xss:修改栈空间大小
// * jdk1.5之前256k
// * jdk1.5之后1m
System.out.println("总内存大小:" + (runtime.totalMemory() / 1024 / 1024));
System.out.println("空闲内存:" + (runtime.freeMemory() / 1024 / 1024));
System.out.println("最大内存:" + (runtime.maxMemory() / 1024 / 1024));
System.out.println(Arrays.toString(args));
Thread.sleep(100000);
}
}
[/wppay]