Java的第八篇文章——Object类、String类和StringBuilder类

简介: Java的第八篇文章——Object类、String类和StringBuilder类

第八章 Object类、String类和StringBuilder类

学习目标

  • 了解Object类及其方法
  • 了解String类及其方法
  • 了解StringBuilder

1.API的概念

应用程序编程接口:每一个技术,官方都会定义出许多的功能,开发人员可以直接拿来使用(拿来主义)。API可以理解为Sun公司已经开发好的类和方法,API文档就是我们开发的帮手。

2.Object类

Object类:所有类的父类,一切类都直接或者是间接继承Object。 Object类中的所有功能,子类都可以使用。

class XX {} //自己的构造方法,继承下来11个方法

Object类定义在了java.lang包,lang包是核心包,此包中的任何类,在使用的时候不需要import 导入。

2.1 Object类的本地方法

本地方法:方法的定义上使用关键字,是修饰符 native ,这个方法就是本地方法。

本地方法的特点:

  • 方法没有方法体
  • 方法是C++语言编写的,Sun公司不开源
  • 法运行的时候,是一个独立的内存 (本地方法栈)
  • 作用 : 凡是遇到本地方法,方法的作用是和本机的操作系统交互的

2.2 Object类的方法toString()

自己定义类Person类,默认的继承Object,Object类定义定义了方法 :

public String toString(); //结果是字符串,就是对象内地地址

输出语句中System.out.println(对象) 调用对象的toString()

System.out.println(对象) == System.out.println(对象.toString()

2.2.1 重写父类方法toString()

public class Person {
    private String name;
    private int age;
    public Person(){}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    /**
     * 重写了父类的方法toString()
     * 返回字符串
     * @return
     * 重写方法目标 : 方法中,返回类中成员变量的值
     */
    public String toString(){
        return name + "::" + age;
    }
}

2.3 Object类的方法equals()

Java技术认为任何对象都具备比较性,Object类定义了方法equals(),作用就是用来比较对象的。方法结果是boolean值,对象相等就是true。

Person p1 = new Person();
Person p2 = new Person(); 
boolean b = p1.equals(p2); // false 对象不相等
  • Object类的方法源码equals
public boolean equals(Object obj){
    return this == obj ;
}
  • 引用数据类型 == 就是比较对象的地址是不是相同的
  • Object类的方法 equals默认比较对象的内存地址

思考:对象的地址有可比性吗?揭阳市榕城区天福路,揭阳市榕城区东三路。 不能比较对象的地址,我们要重写equals方法,建立我们对象Person自己的比较形式。

public class Person {
    private String name;
    private int age;
    public Person(){}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    /**
     * 重写equals,建立Person对象自己的比较方式
     * 比较对象的age年龄,年龄相同返回true
     */
    public boolean equals(Object obj){
        //健壮性判断,如果obj对象的值是null,比较的另一个对象不存在
        if (obj == null){
            return false;
        }
        //判断this和参数obj是不是一个对象 "p1" 如果是,返回true
        //怎么确定this和obj是不是一个对象,内地地址要是一样
        if ( this == obj ) {
            return true;
        }
        //比较对象的年龄,this和obj
        //obj向下转型为Person,安全性判断
        if (obj instanceof  Person) {//obj是Person对象
            Person p = (Person) obj;
            return this.age == p.age;
        }
        //不是Person,没有可比性
        return false;
    }
}

3.String字符串类

  • 字符串对象,程序中定义""都是字符串对象,这个对象的使用频率最高。
  • 字符串类 java.lang.String类,继承Object类,实现了三个接口java.io.Serializable,Comparable<String>,CharSequence
  • 程序中只要你写 "里面任意" 都是String类的对象。
  • 字符串对象是常量,一旦创建不能修改。

3.1 字符串对象创建

public static void main(String[] args) {
    //字符串创建,2个方式
    //直接=创建
    String s = "abc";
    //使用构造方法创建
    String str = new String("aa");
}
  • 直接 = 创建方式,代码少,书写简单,推荐使用
  • new String() 使用了构造方法的创建形式,代码大,不推荐使用

3.2 字符串的实现原理

字符串这个数据类,在Java中是不存在的,字符串的实现原理是用char[]数组表示。

"abc",使用数组char[] ch = {'a','b','c'} ;来表示。

JDK9版本之后,节约内存,char数组改变为了byte数组。

JDK8版本以前都是char数组。

private final char value[]; //JDK中String类的源码

数组的前面的修饰符final,最终的数组,数组一旦建立,数组的地址就被锁死(常量)使用常量的原因,为了线程安全。

3.3 字符串创建对象的区别

String str = "abc"; 
String str = new String("abc");
//两者的创建没有什么区别
public class StringTest {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = new String("abc");
        System.out.println(s1 == s2); //false
        System.out.println("==========");
        /**
         *  s3 = hello 内存中出现String对象,里面是char数组
         *  s3保存的是String对象
         *
         *  s4 = "hello" 和s3中的字符串在内存中的数组表现是一样的
         *  共用
         *  s3的内存地址,赋值给s4
         */
        String s3 = "hello";
        String s4 = "hello";
        System.out.println(s3 == s4); //true
        System.out.println("========");
        String s5 = "how";
        String s6 = "you";
        String s7 = "howyou";
        /**
         *   s7 == (s5+s6)   s5和s6是变量
         *   变量在编译的时候,javac不确定变量的计算结果是什么
         *   运行的时候,JVM会为 s5+s6的结果,新开内存空间
         */
        System.out.println(s7 == (s5+s6)); //false
        System.out.println("============");
        /**
         *  "how"+"you" 是常量,值在编译期间就已经确定
         *  运行,不会建立新的内存空间
         */
        System.out.println(s7 == ("how"+"you"));// true
        String s8 = "a"+"b"+"c";
    }
}
public class ArrayTest {
    public static void main(String[] args) {
        //字符串的不变
        //abc内存是不会改变
        String s = "abc";
        String s1 = s;
        System.out.println(s);
        //变量s,指向了新的字符串对象
        s = "bbc";
        System.out.println(s == s1);//false
//证明是s="bbc"是指向新的地址
    }
}

3.4 String类的构造方法

讲过字符编码,ASCII,小写字母a的值97

  • String(byte[] b) 字节数组转成字符串,使用平台的默认字符集。
  • String(byte[] b,int off,int len) 字节数组转成字符串,使用平台的默认字符集,参数off数组的开始索引,len要转的个数。
  • String(byte[] b,int off,int len,String charsetName) 字节数组转成字符串,使用平台的默认字符集,参数off数组的开始索引,len要转的个数,charsetName参数是你自己可以指定编码表。
public class StringTest {
    public static void main(String[] args) throws UnsupportedEncodingException {
        stringConsByte3();
    }
    //汉字一般的值都是负数
    //String类构造方法相关,和字节,汉字相关
    public static void stringConsByte3() throws UnsupportedEncodingException {
        // String(byte[] bytes)通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
        //平台是操作系统, 默认字符集是GBK(两个字节为一个汉字)
        //强制指定为GBK编码
        byte[] bytes ={-28, -67, -96, -27};
        String str = new String(bytes,"gbk");
        System.out.println(str);
    }
    //String类构造方法相关,和字节,汉字相关
    public static void stringConsByte2(){
        // String(byte[] bytes)通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
        //平台是操作系统, 默认字符集是GBK
        //IDEA 启动的时候,为JVM添加启动参数,默认字符集改成UTF-8(三个字节为一个汉字)
        byte[] bytes ={-28, -67, -96, -27, -91, -67}; // 6字节的数组,转为字符串后是2个汉字
        String str = new String(bytes);
        System.out.println(str);
    }
    //String类构造方法相关,和字节
    public static void stringConsByte(){
       // String(byte[] bytes)通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
        //平台是操作系统, 默认字符集是GBK
        byte[] bytes = {97,98,99,100};
        String str = new String(bytes);
        System.out.println(str);
        //数组的一部分转成字符串
        String str1 = new String(bytes,1,2);//从1索引开始,要2个
        System.out.println(str1);
    }
}
  • String(char[] b) 字节数组转成字符串。
  • String(char[] b,int off,int,len) 字节数组转成字符串,参数off数组的开始索引,len要转的个数。
//String类的构造方法,new String(char[])
public static void stringConsChar(){
    char[] ch = {'a','b','c','d','e'};
    //构造方法,数组转成字符串
    String s = new String(ch);
    System.out.println(s);
    //构造方法,数组转成字符串,转一部分
    String s1 = new String(ch,1,3);//从1索引开始,转3个
    System.out.println(s1);
}

3.5 String类的常用方法

(1)String类的判断类型的方法, 返回都是布尔类型

  • boolean equals(Object obj) 字符串之间的比较,两个字符串相同,返回true
  • boolean equalsIgnoreCase(String str ) 字符串之间的比较,两个字符串相同,返回true,忽略大小写
  • boolean startWith(String str)判断字符串是否以另一个字符串开头,是开头就返回true
  • boolean endsWith(String str)判断字符串是否以另一个字符串结尾,是结尾就返回true
  • boolean contains(String str) 判断字符串中是否包含另一个字符串,完全包含返回true
  • boolean isEmpty()判断字符串的长度是不是0,如果是0返回true
public static void  stringMethod(){
        //boolean equals(Object obj) 字符串之间的比较,两个字符串相同,返回true
        //String类继承Object,重写父类方法,比较的是字符串的实际内容
        String s1 = new String("abc");
        String s2 = new String("abc");
        boolean b = s1.equals(s2);
        System.out.println(b);
        System.out.println("====================");
        //boolean equalsIgnoreCase(String str ) 字符串之间的比较,两个字符串相同,返回true,忽略大小写
        b = "abcdef".equalsIgnoreCase("ABCDEF");
        System.out.println(b);
        System.out.println("=============");
        //boolean startWith(String str)判断字符串是否以另一个字符串开头,是开头就返回true
        b = "HelloWorld.Java".startsWith("Hello");
        System.out.println(b);
        b = "HelloWorld.Java".endsWith(".Java");
        System.out.println("=============");
        System.out.println(b);
        //boolean contains(String str) 判断字符串中是否包含另一个字符串,完全包含返回true
       b = "how are you".contains("are  ");
        System.out.println("=============");
        System.out.println(b);
        //boolean isEmpty()判断字符串的长度是不是0,如果是0返回true
        b = "".isEmpty();
        System.out.println("=============");
        System.out.println(b);
}

(2)String类的获取方法,返回值不一定

  • int length() 返回字符串长度,字符串中字符的个数
  • char charAt(int index) 返回指定索引上的单个字符
  • int indexOf(String str) 返回指定的字符串,在当前字符串中第一次出现的索引
  • int lastIndexOf(String str) 返回指定的字符串,在当前字符串中最后一次出现的索引
  • String substring(int start,int end)截取字符串,参数表示开始索引和结束索引,包含开头索引,不包含结束索引
/**
     * String类的获取方法
     */
    public static void stringMethod2(){
        //int length() 返回字符串长度,字符串中字符的个数
        int length = "abcdef".length();
        System.out.println("length = " + length);
        //char charAt(int index) 返回指定索引上的单个字符
        char ch = "abcdef".charAt(3);
        System.out.println("ch = " + ch);
        //int indexOf(String str) 返回指定的字符串,在当前字符串中第一次出现的索引
        //找不到指定的字符串,返回-1  负数不能作为索引出现
        int index = "how do you do".indexOf(" ");
        System.out.println("index = " + index);
        //int lastIndexOf(String str) 返回指定的字符串,在当前字符串中最后一次出现的索引
        index = "how do you do".lastIndexOf(" ");
        System.out.println("index = " + index);
        //String substring(int start,int end)截取字符串,参数表示开始索引和结束索引,
        // 包含开头索引,不包含结束索引
        String str = "HelloWorld";
        str =  str.substring(2,6);// 返回新的字符串
        System.out.println("str = " + str);
        //substring具有重载写法
        String str1 = "你好我好大家好";
        str1 = str1.substring(3);//从3索引开始,截取到最后
        System.out.println("str1 = " + str1);
}

(3)String的转换方法

  • String toLowerCase() 字符串中的所有内容转成小写
  • String toUpperCase() 字符串中的所有内容转成大写
  • char[] toCharArray() 字符串转成字符数组
  • byte[] getBytes() 字符串转成字节数组 (查询编码表),平台默认字符集
  • byte[] getBytes(String charsetName) 字符串转成字节数组 (查询编码表),指定编码表
  • static String valueOf(任意类型参数) 参数转成字符串对象
/**
     * String类的转换方法
     */
    public static void stringMethod3() throws UnsupportedEncodingException {
        //- String toLowerCase() 字符串中的所有内容转成小写
        // - String toUpperCase() 字符串中的所有内容转成大写
        String str = "abCDefGHJktyM";
        String lower = str.toLowerCase();
        String upper = str.toUpperCase();
        System.out.println("lower = " + lower);
        System.out.println("upper = " + upper);
        //char[] toCharArray() 字符串转成字符数组
        char[] ch = str.toCharArray();
        System.out.println(ch);
        //byte[]  getBytes() 字符串转成字节数组 (查询编码表),平台默认字符集
        String s = "呵呵你好";
        byte[] bytes = s.getBytes("gbk");
        for (int i = 0; i < bytes.length; i++) {
            System.out.println(bytes[i]);
        }
       // static String valueOf(任意类型参数) 参数转成字符串对象
        int i = 1;
        String strI = String.valueOf(i);
        System.out.println(strI+1);
    }

(4) String类的比较方法

int compareTo(String str) 字符串之间的比较,谁大谁小,按照字符顺序(自然顺序)

/**
     * String类的字符串的比较方法,字典顺序
     */
    public static void stringMethod4() throws UnsupportedEncodingException {
        //int compareTo(String str) 字符串之间的比较,谁大谁小,按照字典顺序(自然顺序)
        String str1 = "bcm";
        String str2 = "baz";
        //对象str1调用方法compareTo,参数传递str2
        /**
         *  返回值是int
         *  返回的是 负数,调用者小
         *  返回的是 正数,调用者大
         *  返回是0  一样大
         */
        int i = str1.compareTo(str2);
        System.out.println("i = " + i);
    }

(5)String类的方法,去空格、替换、切割

  • String trim() 去掉字符串两边空格,中间空格不去掉
  • String replace(String oldString,String newString)替换字符串
  • String[] split("规则字符串") 对字符串进行切割
/**
     * String类的方法 去空格,替换,切割
     */
    public static void stringMethod5() throws UnsupportedEncodingException {
        //String trim() 去掉字符串两边空格,中间空格不去掉
        String str = "  abc  def       ";
        System.out.println(str);
        str = str.trim();
        System.out.println("str = " + str);
        //String[] split("规则字符串") 对字符串进行切割
        String splitStr = "aa,bb,cc,dd,ee"; // 逗号,进行切割
        String[] strs = splitStr.split(",");
        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
        //String replace(String oldString,String newString)替换字符串
        String repStr = "how do you do";
        repStr = repStr.replace("o","N");
        System.out.println("repStr = " + repStr);
    }

4.String类正则表达式相关的功能

正则表达式 : 专门用于处理字符串的技术 (正则大神)

  • 字符类 :
  • [abc] 字符串的这个位置只能是abc
  • [^abc] 字符串的这个位置不能是abc
  • [a-zA-Z] 字符串的这个位置必须是字母,52个
  • [^a-zA-Z] 字符串的这个位置必须不能是字母,52个
  • 数字类:
  • [0-9] 字符串的这个位置只能是数字
  • [^0-9] 字符串的这个位置不能是数字
  • [\d] 等同于 [0-9]
  • [\D] 等同于 [^0-9]
  • 预定义字符 :
  • . 匹配所有的字符
  • [\d] 等同于 [0-9]
  • [\D] 等同于 [^0-9]
  • [\w] 文字字符,包含数字,字母,下划线 [a-zA-Z0-9_]
  • [\W] 文字字符,不能包含数字,字母,下划线 [^a-zA-Z0-9_]
  • 数量词 :
  • X{m} X这个字符只能出现m次 a{3}
  • X{m,} X这个字符至少出现m次
  • X{m,n} X这个字符至少出现m次,不超过n次
  • X? X这个字符出现一次,或者一次也没有
  • X* X这个字符出现零次或者多次
  • X+ X这个字符出现至少一次

正则表达式的匹配功能,String类的方法matches()

/**
     *  检查邮箱
     *  规则 :
     * @ 前面 : 可以是数组,字母,混合,_  位数放下
     * @ 后面 : 数组,字母  sina qq 126 1393 yahoo gmail 位数放下
     * . 固定 : com  cn org  edu gov 字母  位数放下
     */
public static void stringMethod2(){
    String email = "shihehe@sina.com";
    String reg = "[\\w]+@[a-z0-9]+(\\.[a-z]+)+";
    boolean b = email.matches(reg);
    System.out.println(b);
}
/**
     *  正则表达式检查手机号是否合法
     *  开头必须是1,长度固定11
     *  第二位3 4 5 6 7 8 9
     *  第三位 必须是都是数字
     */
public static void stringMethod(){
    String tel = "13800138000";
    //定义正则的规则,也是字符串
    String regex = "1[3459678][0-9]{9}";
    //正则规则,和字符串校验
    //String类的方法 matches()
    boolean b = tel.matches(regex);
    System.out.println(b);
}

String类的方法split,也是可以与String类正则表达式关联

public static void stringMethod3(){
        String str = "as123d387654w5465fasfr234567sa";
        String[] strings = str.split("\\d+");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
        System.out.println("================");
        String ip = "192.....168.....35.121";
        String[] ipArray = ip.split("\\.+");
        for (int i = 0; i < ipArray.length; i++) {
            System.out.println(ipArray[i]);
        }
}

5.StringBuilder

StringBuilder是字符串对象的缓冲区对象,缓冲区(出现目的,为了高效)提供String类的效率。

String str = "a"; //字符数组
String str2 = "b";//字符数组
String str3 = str + str2;//字符数组

5.1 StringBuilder类的实现原理

一个可变的字符序列,字符序列就是字符数组

//String 类中 : 
private final char[] value;
//StringBuilder类中 : 
char[] value;

字符序列是数组,Java数组的是定长的,一旦创建,长度固定!

创建对象的时候,StringBuilder中的数组的初始化长度为16个字符

StringBuilder自动的进行数组的扩容,新数组实现,原来数组的中元素复制到新的数组。

结论:无论怎么做字符串的操作,StringBuilder内部永远只有一个数组

StringBuilder类是线程不安全的类,运行速度快 , 推荐使用StringBuilder。

StringBuffer是线程安全的类,运行速度慢,多线程的程序,使用两个类(String和StringBuilder)的构造方法,和其他的方法,一模一样。

相关文章
|
14天前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第17天】本文详细介绍了Java编程中Map的使用,涵盖Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的并发处理和性能优化技巧,适合初学者和进阶者学习。
31 3
|
2月前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
36 0
java基础(13)String类
|
11天前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第14天】Java零基础教学篇,手把手实践教学!
98 65
|
12天前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第19天】本文介绍了Java编程中重要的数据结构——Map,通过问答形式讲解了Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的使用和性能优化技巧,适合初学者和进阶者学习。
36 4
|
13天前
|
存储 SQL 安全
Java零基础-StringBuilder类详解
【10月更文挑战第12天】Java零基础教学篇,手把手实践教学!
18 5
|
12天前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第13天】Java零基础教学篇,手把手实践教学!
33 1
|
14天前
|
存储 SQL 安全
Java零基础-StringBuilder类详解
【10月更文挑战第11天】Java零基础教学篇,手把手实践教学!
12 1
|
16天前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
16 2
|
1月前
|
Java
Java Object 类详解
在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。
|
28天前
|
IDE Java 开发工具
Java“未封闭的 String 表达式”怎么解决
要解决Java中的“未封闭的 String 表示”问题,需检查并修正字符串字面量,确保每个字符串被正确地用双引号括起来。若字符串跨越多行,可使用字符串连接操作符(+)或引入文本块(JDK 13 及以上版本)。这能帮助避免语法错误,并使代码更整洁易读。

热门文章

最新文章