JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)

JAVA学习记录4——常用类

  • 一、JavaBean
  • 二、Object类
    • 1.equals方法
    • 2.hashCode方法
    • 3.toString方法
    • 4.finalize方法
  • 三、包装类
    • 1.基本介绍
    • 2.包装类和基本数据类型的转换
    • 3.包装类型和String类型的转换
    • 4.常用方法
  • 四、String类
    • 1.String的不可变性
    • 2.创建字符串对象的两种方式
    • 3.字符串比较
    • 4.String常用API
  • 五、StringBuilder和StringBuffer
    • StringBuffer
      • 1)基本介绍
      • 2)StringBuffer的构造器
      • 3)String和StringBuffer的转换
      • 4)StringBuffer类的常用方法
    • StringBuilder
    • String、StringBuffer和StringBuilder的比较

一、JavaBean

实体类:在现实世界中能找到实际的个体

JavaBean(或PoJo,Domain)是一种特殊类
Javabean可以理解成实体类,其对象可用于在程序中封装数据。可以将其多个对象再封装到集合类中存储。

标准Javabean须满足以下要求:

  • 成员变量用private修饰
  • 提供每一个成员变量对应的setXX() / getXX() 方法
  • 必须提供一个无参构造器(有参构造器可选)
    需要无参构造器的原因:反射需要

二、Object类

所有类的超类,其中方法所有类都可调用。

1.equals方法

== 和 equals 的对比:

==既可判断基本类型,又可判断引用类型。如果判断基本类型,判断的是值是否相等;如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象。

equals:Object类中方法,只能判断引用类型
默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等(如:String类中重写equals,用于判断字符串内容是否相同)

"abc".equals("abc"); //true

可仿照equals方法源码,在自定义类中重写,重写equals的内部仍可应用原本的equals方法判断

public boolean equals(Object anObject) {
	if (this == anObject) {
        return true; //如果是同一对象,直接返回true
    }
    if (anObject instanceof String) { //是此类才比较
        String anotherString = (String)anObject; //向下转型,因为要用到anObject的属性
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

2.hashCode方法

返回对象的哈希码值(十进制)。
对象名.hashCode()

特点:

  1. 提高具有哈希结构的容器的效率
  2. 两个引用,如果指向的是同一个对象,则哈希值必然一样
  3. 两个引用,如果指向的是不同对象,则哈希值不一样
  4. 哈希值主要根据地址号而来,不能完全等价于地址
  5. 在集合中如果需要,会进行重写

3.toString方法

返回该对象的字符串表示

默认返回:全类名(包名+类名)+@+哈希值的十六进制
子类往往重写toString方法,用于返回对象的属性信息

重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式

当直接输出一个对象时,toString方法会被默认的调用
System.out.println(对象);等同于调用输出
对象.toString()

4.finalize方法

  1. 当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做自己的业务和逻辑(如释放资源,数据库连接,打开文件)
  2. 什么时候被回收:当某个对象没有任何引用时,JVM就认为这是一个垃圾对象,会使用垃圾回收机制来销毁对象,销毁之前,会先调用finalize方法
  3. 垃圾回收机制的调用由系统决定(有自己的GC算法),也可通过System.gc() 主动触发垃圾回收机制

三、包装类

1.基本介绍

针对八种基本数据类型相应的引用类型,就是包装类(Wrapper)。有了类的特点,就可以调用类中的方法

基本数据类型 包装类
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double

其中Byte、Short、Integer、Long、Float、Double都是Number类的子类,Number和Boolean、Character都是Object的子类
JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第1张图片

2.包装类和基本数据类型的转换

装箱:基本数据类型 —> 包装类
拆箱:包装类 —> 基本数据类型

jdk5前的手动装箱和拆箱

//手动装箱 int -> Integer
int n1 = 100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱 Integer -> int
int i = integer.intValue();

jdk5后(含jdk5)的自动装箱和拆箱
自动装箱底层调用的是valueOf方法,如Integer.valueOf()

int n1 = 100;
Integer integer = n1; //可直接赋值,本质不变
int n2 = integer;

3.包装类型和String类型的转换

包装类 —> String:

  1. 直接加" "转换,对原数据的类型无影响
    eg:
Integer i = 100;
String str1 = i + "";//i仍是Integer
  1. toString方法
    String str2 = i.toString();
  2. String.valueOf
    String str3 = String.valueOf(i);

String —> 包装类:

String str = "123";
//parseInt方法
Integer i = Integer.parseInt(str);//使用到自动装箱
//创建对象
Integer i1 = new Integer(str);//用构造器

4.常用方法

Integer类:
Integer.MIN_VALUE 返回最小值
Integer.MAX_VALUE 返回最大值

易错案例:
JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第2张图片
JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第3张图片

Character类:
JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第4张图片

四、String类

1.String的不可变性

String是字符串类型,可以定义字符串变量指向字符串对象。用Unicode字符编码。字符串内容用String中的属性 private final char value[];存放字符串内容

String类实现了Serializable接口,说明String可以串行化(串行化意味着对象可以在网络传输);实现了Comparable接口,说明了String对象可以比较

String是final类,创建的字符串对象(地址)不可改变," “方式给出的字符串对象,在堆中的字符串常量池中存储。每次修改其实是产生并指向了新的字符串对象,原对象没有改变
eg:下面输出name为ABCD,但字符串常量池中存有"AB"和"CD”,name指向相加的结果

String name = "AB"; 
name += "CD";
System.out.println(name);

2.创建字符串对象的两种方式

  1. 直接用" "形式定义
  2. 通过String类的构造器创建

JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第5张图片
new String(char[] a,int startIndex,int count)

String s1 = new String();

String s2 = new String("ABC"); //前两种几乎不用

char[] chars = {'A','B','C'};
String s3 = new String(chars);
byte[] by = {97,98,99,65,66,67};
String s4 = new String(by); //转成字符串输出

区别:

  • 用" "方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份。创建时若常量池已有,则直接指向
  • 通过构造器new对象,每次new都会产生一个新对象,放在堆内存中,里面维护了value属性,指向常量池中相应内容的数据空间(没有就创建,有就直接指向)
char[] chars = {'A','B','C'};
String s3 = new String(chars);
String s2 = "ABC";
System.out.println(s2 == s3); //s2,s3指向不同
输出false
System.out.println(s2.equals(s3)); //比较字符串值
输出true
System.out.println(s2 == s3.intern()); //s3指向堆,s3.intern指向常量池
输出true
System.out.println(s3 == s3.intern());
输出false
Person p1 = new Person();
p1.name = "abc";
Person p2 = new Person();
p2.name = "abc";
System.out.println(p1.name == p2.name);
//p1,p2是不同对象,但其中的name属性均指向常量池中的abc,所以相同
输出true
System.out.println(p1.name == "abc");
//属性在堆中存储,指向常量池,与"abc"指向相同
输出true

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2);
//s1,s2都指向常量池中同一地址,但s1,s2本身是两个对象,地址不同
输出false

JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第6张图片

JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第7张图片
eg:

String s2 = new String("ABC");//实际上创建了两个对象,在常量池和堆区中,s2指向堆区中的
String s1 = "abc"; //实际上创建了0个对象,因为原本要在常量池创建,但已有重复字符串,s1指向常量池中的
//s1 != s2

字符串相加的实现
" "常量相加在池中

String s1 = "abc";
String s1 = "a"+"b"+"c";
//Java存在编译优化机制,编译时"a"+"b"+"c"会转化为"abc",提高运行性能
//反编译可验证
s1 == s2 true!!!

变量相加在堆中

String s1 = "hello";
String s2 = "abc";
String c = s1 + s2;

c指向堆中的value,value指向池中的"helloabc"(相当于用new String创建的对象)
JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第8张图片
toString()方法的底层就是new String对象

3.字符串比较

用==判断会出错,因为" “创建的对象指向常量池,输入的字符串指向堆区
可用String类提供的equals比较
equalsIgnoreCase可忽略大小写比较

String name = "abc";
String name1 = "ABC";
name.equals(name1); //return false
name.equalsIgnoreCase(name1); //return true

在这里插入图片描述

4.String常用API

toUpperCase、toLowerCase、compareTo与char相同。
JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第9张图片
遍历字符串中字符:

String str = "ABCDE";
for (int i = 0; i < str.length(); i++) {
	char ch = str.charAt(i);
	System.out.println(ch);
}

intern() 方法:
intern() 方法返回字符串对象的规范化表示形式。

它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

返回值:字符串常量池中与传入对象内容相同的字符串地址。若无相同的,则将此String对象添加到池中,并返回此对象的引用

indexOf:获取字符在字符串中第一次出现的索引,从0开始,找不到则返回 -1
lastIndexOf:获取字符在字符串中最后一次出现的索引,从0开始,找不到则返回 -1

trim:去前后空格

concat:拼接字符串,可连续拼接
String s1 = s1.concat("abc").concat("def");

format:格式化字符串%s、%c、%d、%f

五、StringBuilder和StringBuffer

String类每次更新、拼接需要重新开辟空间,效率较低,StringBuilder和StringBuffer可增强String的功能,提高效率。

StringBuffer

1)基本介绍

StringBuffer代表可变的字符序列,可对字符串内容进行增删(长度可变),StringBuffer是一个容器

StringBuffer本身是final类,不可被继承。在StringBuffer的父类AbstractStringBuilder中有属性 char[] value(不是final),存放字符串内容,因此存放在堆中。StringBuffer的增删不用每次都创建新对象,更高效

2)StringBuffer的构造器

JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第10张图片

3)String和StringBuffer的转换

String —> StringBuffer

String s = "hello";
//方式一:使用构造器
StringBuffer b1 = new StringBuffer(s);
//方式二:使用append方法
StringBuffer b2 = new StringBuffer();
b2.append(s);

StringBuffer —> String

//方式一:使用toString方法
String s1 = b1.toString();
//方式二:构造器
String s2 = new String(b1);

4)StringBuffer类的常用方法

  1. 增——append()
  2. 删——delete(start,end)
  3. 改——replace(start,end,string)将[start,end)间的内容替换
  4. 查——indexOf()查找子串在字符串第一次出现的索引
  5. 插入——insert(index,string)在index处插入string,原索引为index的内容自动后移
  6. 获取长度——length()

JAVA学习记录7——常用类(OBject类、包装类、String类、StringBuilder和StringBuffer)_第11张图片

StringBuilder

一个可变的字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步(不是线程安全的)。该类被设计用作StringBuffer的一个简易替换。

StringBuilder的方法没有做互斥的处理,即没有synchronized关键字,因此用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先用此类,因为在大多数实现中,它比StringBuffer快。

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

String、StringBuffer和StringBuilder的比较

  • String:不可变字符序列,效率低,复用率高
  • StringBuffer:可变字符序列,效率较高(增删),线程安全
  • StringBuilder:可变字符序列,效率最高,线程不安全

String s = "a"; s +="b"; 丢弃了原对象,产生了字符串"ab",s指向新对象"ab"。多次改变串内容,会导致大量副本字符串对象留在内存中,降低效率。
对字符串做大量修改不要用String。很少修改,被多个对象引用使用String(如配置信息)

你可能感兴趣的:(笔记,Java,java,学习,后端,经验分享,开发语言)