项目1 StringBuilder
StringBuilder是一个可变的字符序列——在类中提供了修改私有成员变量的方法——没有提供修改私有成员的方法
String是不可变的字符序列
String长度本身也不可以变化,StringBuilder长度可以变化,可以认为StringBuilder就像一个可以伸缩的容器,用于存储字符
常用方法
构造方法作用
创建当前对象、将其他类型的数据,转换成当前类型
StringBuilder sb = new StringBuilder("abc");
- capacity():获取当前生成器的容器大小
- length():获取当前生成器中的字符个数
- StringBuilder():创建一个生成器,初始容量为16个字符
- StringBuilder(int capacity):创建一个生成器,初始容量为capacity大小
- StringBuilder(String str):创建一个生成器,初始值就是str这些字符,初始大小是str+16
append添加功能
append(任意类型):可以将任意数据类型,转成字符,添加到生成器中
insert添加功能
insert(int index, 任意数据类型):可以将任意数据类型,添加到指定的位置
index的范围是0~当前缓冲区的大小;数据本身的索引就是参数中指定的index
sb.append("xyz"); // 追加在末尾
System.out.println(sb);
sb.insert(1, "hello"); // 在相应的位置插入
删除功能
deleteCharAt(int index) :删除指定索引的字符
delete(int start, int end):删除指定范围的字符,被删除的部分包含头不包含尾
替换和反转功能
1、replace(int start, int end ,String str):
将字符串缓冲区中的从start开始到end-1这部分内容,替换成str
sb.replace(1, 3, “hello”); //替换
2、reverse():
将原有字符序列进行反转
sb.reverse(); //反转
项目2 String和StringBuilder拼接字符串的区别
String类型拼接字符串
1、创建一个StringBuilder的存储空间,大小为第一个字符串的长度+16(第一个对象)
2、将第一个字符串添加到缓冲区中
3、将第二个字符串添加到缓冲区中
4、将缓冲区对象转成字符串对象(创建了一个新的字符串对象)(第二个对象)
5、返回该字符串对象
String 拼接 时间和内存空间都很浪费
StringBuilde
1、创建一个新的StringBuilder的存储空间
2、在StringBuilder的基础上进行添加,不创建新的字符串
3、循环完成后,将StringBuilder转成String
无论循环多少次,只创建两个对象 节省时间和内存空间
String和StringBuilder的相互转换
String str = "abc";
StringBuilder sb = new StringBuilder(str);
String result = sb.toString();
项目3 StringBuffer和StringBuilder的区别
相同点:
都是字符串的缓冲区,都是字符串的生成器,都是可变的字符序列
不同点:
1、出现版本不同:
StringBuffer在jdk1.0出现的
StringBuilder在jdk1.5出现的
2、线程安全性不同:
StringBuffer是线程安全的,在多线程环境下仍然保证数据安全
StringBuilder是线程不安全,在多线程环境下无法保证数据安全
3、效率不同:
StringBuffer效率低
StringBuilder效率高
项目4继承
继承就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
好处
- 提高代码的复用性。
- 类与类之间产生了关系,是多态的前提。
继承的格式
class 父类 {
...
}
class 子类 extends 父类 {
...
}
小贴士:Fu 类中的成员变量是非私有的,子类中可以直接访问。若Fu 类中的成员变量私有了,子类是不能直接访问的。通常编码时,我们遵循封装的原则,使用private修饰成员变量,那么如何访问父类的私有成员变量呢?对!可以在父类中提供公共的getXxx方法和setXxx方法。
子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用super
关键字,修饰父类成员变量
项目5 重写
方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。
特点:
- 方法名和参数列表必须相同。
- 子类重写父类的方法的时候,返回值类型必须是父类方法的返回值类型或该返回值类型的子类。不能返回比父类更大的数据类型。
- 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
重载与重写的区别
1、重载(overload):
前提: 所有的重载方法必须在同一个类中
特点:
- 方法名相同,参数列表不同,与其他的无关(访问控制符、返回值类型)
2、重写(override):
前提: 有继承关系
特点:
- 方法名和参数列表必须相同。
- 子类重写父类的方法的时候,返回值类型必须是父类方法的返回值类型或该返回值类型的子类。不能返回比父类更大的数据类型。
- 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
继承后的特点
- 构造方法的名字是与类名一致的。所以子类是无法重写父类构造方法的。
- 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。
项目6 super和this
-
super :代表 父类的引用。
-
this :代表 当前对象的引用。
this(…) – 本类的构造方法
super(…) – 父类的构造方法
项目7 instanceof关键字
instanceof关键字:该关键字用来判断一个对象是否是指定类的对象。属于比较运算符
用法:
对象 instanceof 类;
该表达式是一个比较运算符,返回的结果是boolean类型 true|false
使用instanceof关键字做判断时,两个类之间必须有关系
项目8 Object类
Object类是所有类型的顶层父类,所有类型的直接或者间接的父类;所有的类型中(包括数组)都含有Object类中的所有方法。
Object类的构造方法:Object()
1、可以自己创建对象
2、让子类访问,所有子类都会直接或者间接的访问到这个顶层父类的构造方法
Object类的常见方法
hashCode方法
hashcode()表示的是JVM虚拟机为这个Object对象分配的一个int类型的数值
JVM会使用对象的hashcode值来提高对:HashSet 、HashMap、Hashtable哈希表存取对象的使用效率。
生成数字的原则
同一个对象多次调用hashCode方法,【必须】返回相同的整数(程序多次运行不要求哈希码值保证一致)
int num = u1.hashCode(); // 获取对象的哈希码值
使用equals方法判断相同的两个对象,【必须】返回相同的整数(equals方法是用于决定两个对象是否相同的方法)
使用equals方法判断不相同的两个对象,【尽量】返回不相同的整数(不做强制要求)
Object类型的hashCode,【确实】会根据不同的对象生成不同的整数。
生成hashCode常见的算法 MD4、MD5、SHA-1
toString方法
返回当前对象的字符串表示。
Object类型中内容为:对象的地址值
重写父类的这个方法
//重写Object类的toString方法
public String toString() {
//return "xxx";
return id+"\t"+name+"\t"+age;
}
equals方法
Object 中用于比较两个对象是否相等的方法,比较的就是“调用者”和“参数”这两个对象
boolean equals(Object obj)
性质:
-
自反性:自己和自己相等
-
对称性:A和B相等,那么B就和A相等。A.equals(B)为true,那么B.equals(A)也为true
-
传递性:A.equals(B)为true,并且B.equals©为true,那么A.equals©也为true
-
一致性:A多次调用equals方法用于和B对象比较,应该返回相同的判断结果
-
在Object类型中,比较的是两个引用是否指向了同一个对象。如果是,才返回true。相当于是在比较两个对象的地址值是否相同。
重写equals方法
public class User{
private int id;
private String name;
private int age;
public User(){
}
public User(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
//重写equals方法
public boolean equals(Object obj){
//定义规则: User类对象的 id name age 都相同时,就返回true 其他返回false
// this 和 参数obj的比较
User u = (User)obj; // 强转
if(this.id==u.getId() && this.name.equals(u.getName()) && this.age==u.getAge()){
return true;
}else{
return false;
}
}
}
项目9==和equals方法的区别
相同点
==和equals都是用于比较数据是否相等的方式。
不同点
1、比较内容的不同:
==可以比较任意数据类型,既可以比较基本数据类型,也可以比较引用数据类型
equals方法只能比较引用数据类型
2、比较规则不同:
==在比较基本类型的时候,比较的是数据的值;比较引用类型时,比较的是地址值
equals方法在重写之前,比较的是两个对象的地址值;在重写之后,安装重写的方式对比
项目10final关键字
final是个修饰符。
final的含义是“终极版本。
final可以修饰变量,方法,类,方法参数。
1.2final修饰变量
此时的变量转为常量。
此变量在第一次被赋值后,再不能修改它的值。
示例代码
public class Test{
private final int age=10; // 必须赋值
public void method(){
age = 100; // 编译报错,不能重新赋值
}
}
成员常量一般也做成static类型,因为没有必要为每个实例提供一份根本不会变化的变量空间
常量的定义规则
public static final double PI=3.14;
1:public :访问权限最大
2:static :内存中只有一份
3:final :是一个常量
4:常量名大写,多个单词用下划线(_)分隔
5:必须初赋值,赋值后,不能重新赋值。
示例代码
public class Demo01_final修饰变量 {
}
class Constants{ //定义常量类----这个类中全都存放常量
public static final double PI = 3.14;
public static final int DAY_OF_WEEK = 7;
}
class A{
public final String str = "ADMIN"; // 被final修饰的成员变量
// 在java中定义常量 的格式通常是:
public static final double PI=3.14;
public void hello(){
System.out.println(Constants.DAY_OF_WEEK); // 使用常量
}
}
案例
定义静态方法求圆的面积
定义静态方法求圆的周长
发现方法中有重复的代码,就是PI,圆周率。如果需要提高计算精度,就需要修改每个方法中圆周率。
public static final double PI = 3.14; // 静态常量
public static double getArea(double r) {
return PI * r * r;
}
public static double getLength(double r) {
return PI * r * 2;
}
1.3final修饰方法
特点:该方法是最终方法,不能被子类重写。
class A{
public final void sayHello(){
System.out.println("你好");
}
}
class B extends A{
public void sayHello(){ // 编译报错——不能重写父类中被final修饰的方
}
}
1.4final修饰类
该类是最终类,不能被继承。
查看api文档发现String类是final的。Integer类也是final的。
为了防止代码功能被重写,该类没有必要进行扩展。
final class AA{
}
class BB extends AA{ // 编译报错——被final修饰的类,不能被继承 jdk中的String类就是不能被继承的
}
1.5final修饰局部变量
final修饰的局部变量不能重新赋值。
class X{ // final修饰局部变量
public void hello(){
final int x = 100;
x = 200; //final修饰的局部变量,不能重新赋值
}
}
1.6final修饰形参
- 当形参被修饰为final,那么该形参所属的方法中不能被篡改(重新赋值)。
- 项目中主要用于一些只用来遍历未知数据的方法。将未知变量声明为final的。增强数据的安全性。
public class TestFinal {
/*
* 用final修饰方法的形参
* */
public static void printStudentName(final Student s){
//s.setName("yyy"); // 这句不是为形参重新赋值 并没有修改地址
//s = new Student(2,"李四"); // 因为final修饰了形参,所以不能重新赋值
System.out.println(s.getName());
}
public static void add(final int x, final int y){
/* 因为final修饰了 形参,所以在方法中不能为 形参重新赋值
x = 10;
y = 10;
*/
System.out.println(x+y);
}
public static void main(String[] args) {
Student s = new Student(1,"xxx");
printStudentName(s);
add(100, 100);
}
}