【JavaSE 第十二天】

【JavaSE 第十二天】

一、 API 的概念

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

二、 Object 类

Object 类:是所有类的父类,一切类都直接或者间接继承 Object 类,Object 类中的所有功能,子类都可以使用。
好处:只要是定义一个类,他就拥有自己的构造方法,并继承来自 Object 的 11 个方法。

class XX {}  //拥有自己默认的构造方法,并继承来自 Object 的 11 个方法
  • 原因:Object 类定义在了 java.lang 包上, lang 包是核心包,此包中的任何类,在使用的时候不需要 import 导入
    Object 类的构造方法:Object(); 但是第一行中不是 super();

1. Object 类的本地方法

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

本地方法的特点

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

2. Object 类的方法 toString()

  • 自己定义的类 Person类,默认继承 Object 类,Object 类已经定义了方法:
public String toString();   // 结果是字符串,就是对象内存地址
  • 输出语句中 System.out.println(对象); (默认)调用对象的 toString();方法
    System.out.println(对象); 就相当于: System.out.println( 对象.toString() );
public class Person {

}
    public static void main(String[] args) {
        Person person=new Person();
        // 调用 person 对象的方法 toString();
        String s = person.toString();
        // 打印出的是对象在内存中的 “地址”
        System.out.println("s = " + s);
        // 输出语句中必须(默认)调用对象的方法 toString();
        System.out.println("person = " + person);
    }
  • toString 方法的结果,和开发没有任何的关系。 我们需要的是重写父类的方法 toString(); ,建立我们对象自己的字符串表现形式
(1) 重写父类的方法 toString()

原本的父类写法为:

public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

重写:

public class Person {
    private String name;
    private int age;
    public Person(){} // 无参构造器
    // 有参构造器
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

3. Object 类的方法 equals()

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

  • 自己进行对象的比较

创建 Person 类:

public class Person {

}

调用并比较:

public class ObjectTest {
    public static void main(String[] args) {
        // 创建两个对象
        Person p1=new Person();
        Person p2=new Person();
        // p1 和 p2 对象进行比较
        boolean b=p1.equals(p2);
        System.out.println(b);
    }
}
  • Object 类的方法源码: equals 部分
public boolean equals(Object obj){
    return (this == obj);
}
  • return (this == obj) 就是比较对象的地址(引用数据类型)是不是相同的

  • Object 类的方法 equals() 默认比较对象的内存地址
    equals 比较对象

  • 但是对象的地址不具有可比性,所以我们不能比较对象的地址,所以我们要重写 equals() 方法,建立我们创建的对象的自己的比较方式

建立我们对象 Person 自己的比较形式
重写 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){
        // this 是调用者 p1 、 obj 是参数即比较的对象 p2
        // this 就是指代 p1 、 obj 就是指代 p2
        // 比较 this 对象的年龄 和 参数obj的年龄
        // 一、健壮性判断的问题:如果 obj 对象的值是 null ,比较的另一个对象并不存在则直接返回 false 提高运行效率
        if(obj==null){
            return false;
        }
        // 存在多态的类型提升问题:对象 p2 是子类 但是 obj 是一个父类,如果传递进入 obj 就会出现类型提升问题(这是默认提升的),就不能调用子类特有的成员,所以要强制类型转换
        // 要进行比较对象的年龄,只能将 obj 向下转型为 Person 类
        // Person p=(Person)obj;
        // return this.age==p.age;
        // 但是此类操作存在安全隐患
        // 二、判断 this 和 obj 是不是一个对象的问题:如果是直接返回 true 提高运行效率
        // 怎么确定 this 和 obj 是不是一个对象:内存地址是否一样
        if(this==obj){
            return true;
        }
        // 三、必须事先判断 obj 是否是 Person 对象,才能够转换
        if(obj instanceof Person){
            // 判断 obj 是否是 Person 类的对象
            Person p=(Person)obj;
            return this.age==p.age;
        }
        // 如果不是 Person 类的对象则直接返回 false
        return false;
    }
}

调用:

class Cat{}
public class ObjectTest {
    public static void main(String[] args) {
        // 创建两个对象
        Person p1=new Person("张三",5);
        Person p2=new Person("李四",6);
        // p1 和 p2 对象进行比较
        boolean b1=p1.equals(new Cat());
        System.out.println(b1);
        boolean b2=p1.equals(p1);
        System.out.println(b2);
        boolean b3=p1.equals(p2);
        System.out.println(b3);
    }
}

三、 String 字符串类

字符串对象,程序中定义 " " 都是字符串对象,这个对象的使用频率最高。
字符串类: java.lang.String 类,继承自 Object 类,实现了三个接口。
程序中只要写 “…” 都是 String 类的对象。
字符串对象是常量,一旦创建不能修改。(为了线程安全)

1. 字符串对象的创建

    public static void main(String[] args) {
        // 字符串创建方式,共有两种:
        // 1.直接创建的方式
        String s="直接创建的方式";
        // 2.使用构造方法创建的方式
        String str="使用构造方法创建的方式";
        // 因为原 String 类中具有这种自带的构造方法
    }
  • 直接创建的方式,代码少,书写简单,推荐使用
  • new String() 方式,使用了构造方法的创建形式,代码量大,不推荐使用

2. 字符串的实现原理

字符串这个数据类型,在 Java 中是不存在的,字符串的实现原理是用 char[] 数组表示
例如:“abc”,这个字符串是使用数组 char[] ch = {'a','b','c'} ; 以这种形式来表示
JDK9 版本之后,为了节约内存,从 char 数组 改变为了 byte 数组
JDK8 版本以前都是 char 数组

private final char value[]; // JDK 中 String 类型的源码表现
  • 数组的前面的修饰符 final,使它成为最终的数组,数组一旦建立,数组的地址就被锁死(常量)。使用常量的原因:是为了线程安全
    数组被 private 修饰,是私有的,并且类中其中并不提供 get/set 方法,无法改动

字符串的不变性解释

    public static void main(String[] args) {
        // 字符串的不变性解释:
        // abc 的内存地址是不会改变的
        String s="abc";
        System.out.println("s = " + s);
        // 变量 s ,指向了新的字符串对象,其实是 s 的引用地址发生了变化
        s="bbc";
        // abc 和 bbc 在根本上是不会发生改变的,仍在那一块地址内存中
        System.out.println("s = " + s);
        // 类似于: int a=1;  a=2;  1 和 2 本身不会变化,只是 a 被赋予的值变化
    }

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 地址内存不同
        // 第二种情况:
        /**
         *  s3 ="hello" 内存中出现 String 对象,里面是 char 类型的数组
         *  s3 保存的是 String 对象
         *  s4 ="hello" 和 s3 中的字符串在内存中的数组表现是一样的
         *  所以就会共用
         *  导致 s3 的内存地址,赋值给 s4
         */
        String s3="hello";
        String s4="hello";
        System.out.println(s3==s4); // 结果是 true
        // 第三种情况:
        /**
         *   s7 == (s5+s6)   s5 和 s6 是变量
         *   变量在编译的时候,javac 不确定变量的计算结果是什么
         *   运行的时候,JVM 会为 s5+s6 的结果,新开内存空间
         */
        String s5="ni";
        String s6="hao";
        String s7="nihao";
        System.out.println(s7==(s5+s6)); // 结果是 false
        // 第四种情况:
        /**
         *  "how"+"you" 是常量,值 在编译期间就已经确定
         *  运行的时候,不会建立新的内存空间
         */
        System.out.println(s7==("ni"+"hao")); //结果是 true
        /**
         *  变量在编译时编译器不知道是什么值,并不确定
         *  常量在编译时编译器已经确定了,直接编译为常量
         */
        // 第五种情况:
        String s8="a"+"b"+"c";
        // 编译时直接编译为 "abc" 所以只创建了一个对象
    }
    public static void print(){
        // abc 的内存地址是不会改变的
        String s="abc";
        System.out.println("s = " + s);
        // 变量 s ,指向了新的字符串对象,其实是 s 的引用地址发生了变化
        s="bbc";
        // abc 和 bbc 在根本上是不会发生改变的,仍在那一块地址内存中
        System.out.println("s = " + s);
        // 类似于: int a=1;  a=2;  1 和 2 本身不会变化,只是 a 被赋予的值变化
    }
}

4. String 类的构造方法

(1) 字节编码
  1. 字符编码:ASCII, 小写字母 a 的值97,大写字母 A 的值是65,数字是48到57
    ASCII 是美国标准信息交换代码,一个字节编码代表一个字符
  2. 中国(GB2312(大约4000个汉字)、GBK(大约20000个汉字,还有少数民族语言)、GB18030(尚未启用)),简体中文的编码表,汉字是用两个字节编码代表,并且两个字节编码都是负数的形式,防止与 ASCII 冲突
  3. ISO 国际标准化组织:全球的语言放在一个编码表中,万国语言标准:Unicode
    UTF-8 :存储全球的文字(字节表示变长,但是能用一个字节表示的,绝不用两个字节表示,为了节省资源),在其中汉字用三个字节表示且都是负值
    UTF-16 :定长表示,无论什么字符全部都是两个字节存储
(2) 常用的 String 类的构造方法
① 字节数组转成字符串
  • String(byte[] b) 字节数组转成字符串,使用平台的默认字符集
  • String(byte[] b,int off,int len) 字节数组转成字符串,使用平台的默认字符集,参数 off 指的是:数组的开始索引,len 指的是:要转的个数
  • String(byte[] b,int off,int len,String charsetName) 字节数组转成字符串,使用平台的默认字符集,参数 off 指的是:数组的开始索引,len 指的是:要转的个数,charsetName 参数是自己可以指定编码表

使用:

import java.io.UnsupportedEncodingException;

public class StringTest {
    public static void main(String[] args) throws UnsupportedEncodingException {
        stringConsByte3();
    }
    
    // 1.String 类构造方法相关:和字节相关
    public static void stringConsByte(){
        // String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
        // 平台是操作系统,Windows 的默认字符集是 GBK
        byte[] bytes = {97,98,99,100};  // 必须在 byte 的字节限制范围内
        String str = new String(bytes);
        System.out.println(str);
        // 数组的一部分转成字符串
        String str1 = new String(bytes,1,2); // 表示从1索引开始,要2个  写多了就会出现越界异常
        System.out.println(str1);
    }

    // 2.String 类构造方法相关:和汉字相关
    public static void stringConsByte2(){
        // String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
        // 原本 Windows 的默认字符集是 GBK
        // 但是 IDEA 启动的时候,为 JVM 添加启动参数,默认字符集改成 UTF-8
        byte[] bytes ={-28, -67, -96, -27, -91, -67}; // 在 UTF-8 中,6字节的数组,转为字符串后是2个汉字
        String str = new String(bytes);
        System.out.println(str);
        String str1=new String(bytes,0,3); // 准确选择几个,否则汉字出不来
        System.out.println(str1);
    }

    // 3.String 类构造方法相关:和字节、汉字相关
    public static void stringConsByte3() throws UnsupportedEncodingException {
        // String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
        // Windows 的默认字符集是 GBK
        // 在 IDEA 中强制指定为 GBK 编码
        byte[] bytes ={-28, -67, -96, -27};
        String str = new String(bytes,"GBK");
        System.out.println(str);
    }
}
② 字符数组转成字符串
  • String(char[] b) 字符数组转成字符串
  • String(char[] b,int off,int len) 字符数组转成字符串,参数 off 数组的开始索引,len 要转的个数

与编码表无关

    public static void main(String[] args) {
        stringConsChar();
    }
    // String 类的构造方法,new String(char[])
    public static void stringConsChar(){
        char[] ch={'a','b','c','d','e'};
        // 通过构造方法,数组转成字符串
        String s = new String(ch);
        System.out.println("s = " + s);
        // 通过构造方法,数组转成字符串,转一部分
        String s1 = new String(ch,1,3); // 从索引一开始,转三个
        System.out.println("s1 = " + s1);
    }

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 main(String[] args) {
        stringMethod();
    }
    /**
     *  String 类的判断方法
     */
    public static void stringMethod(){
        // 1. 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 = " + b);
        // 2. boolean equalsIgnoreCase(String str ) 字符串之间的比较,两个字符串相同,返回 true,忽略大小写
        // 简化写法:
        b="abcde".equalsIgnoreCase("ABCDE");
        System.out.println("b = " + b);
        // 3. boolean startWith(String str) 判断字符串是否以另一个字符串开头,是开头就返回 true,严格区分大小写
        //    boolean endsWith(String str) 判断字符串是否以另一个字符串结尾,是结尾就返回 true,严格区分大小写
        b="HelloWorld".startsWith("Hello");
        System.out.println("b = " + b);
        b="HelloWorld".endsWith("World");
        System.out.println("b = " + b);
        // 4. boolean contains(String str) 判断字符串中是否包含另一个字符串,完全包含返回 true,严格区分大小写
        b="how are you".contains("are"); // true
        b="how are you".contains("era"); // false
        System.out.println("b = " + b);
        // 5. boolean isEmpty() 判断字符串的长度是不是0,如果是0返回 true
        b="".isEmpty();
        System.out.println("b = " + b);
    }
(2) String 类的获取方法,返回值不一定(有可能找得到,有可能找不到,有可能有多个,有可能没有)
  • int length() 返回字符串长度,字符串中字符的个数
  • char charAt(int index) 返回指定索引上的单个字符
  • int indexOf(String str) 返回指定的字符串,在当前字符串中第一次出现的索引
  • int lastIndexOf(String str) 返回指定的字符串,在当前字符串中最后一次出现的索引
  • String substring(int start,int end) 截取字符串,参数表示开始索引和结束索引,包含开头索引,不包含结束索引
    public static void main(String[] args) {
        stringMethod();
    }

    /**
     *  String 类的获取方法
     */
    public static void stringMethod(){
        // 1.int length() 返回字符串长度,字符串中字符的个数
        int length="abcdef".length();
        System.out.println("length = " + length);
        // 2.char charAt(int index) 返回指定索引上的单个字符
        char ch="abcdef".charAt(3); // 结果是 d  输入的参数超过了原限制就会发生越界异常
        System.out.println("ch = " + ch);
        // 3.int indexOf(String str) 返回指定的字符串,在当前字符串中第一次出现的索引
        // 找不到指定的字符串,就返回 -1 ,因为负数不能作为索引出现
        int index="how do you do".indexOf("d");
        System.out.println("index = " + index);
        // 4.int lastIndexOf(String str) 返回指定的字符串,在当前字符串中最后一次出现的索引
        int last="how do you do".lastIndexOf(" ");
        System.out.println("last = " + last);
        // 5.String substring(int start,int end) 截取字符串,参数表示开始索引和结束索引,包含开头索引,不包含结束索引
        String str="HelloWorld";
        str = str.substring(2,6); // str.substring(2,6); 直接这样不赋值打印就会出现:"HelloWorld",因为它的值是锁死的,截取需要给变量重新赋值才能打印出来截取的值
        System.out.println("str = " + str);
        String str2="HelloWorld";
        str2=str2.substring(0,str2.length()); // 这是截取全部
        System.out.println("str = " + str2);
        // substring 这个方法具有重载方法
        String str1="你好我好大家好";
        str1=str1.substring(3); // 从索引3开始,截取到最后
        System.out.println("str1 = " + str1);
        String str3="你好我好大家好";
        str3=str3.substring(0);
        System.out.println("str1 = " + str3); // 这也是截取全部
    }
(3) String 类的转换方法
  • String toLowerCase() 字符串中的所有内容转成小写
  • String toUpperCase() 字符串中的所有内容转成大写
  • char[] toCharArray() 字符串转成字符数组
  • byte[] getBytes() 字符串转成字节数组 (查询编码表),平台默认字符集
  • byte[] getBytes(String charsetName) 字符串转成字节数组 (查询编码表),指定编码表
  • static String valueOf(任意类型参数) 参数转成字符串对象
    public static void main(String[] args) throws UnsupportedEncodingException {
        stringMethod();
    }
    /**
     * String 类的转换方法
     */
    public static void stringMethod() throws UnsupportedEncodingException {
        // 1.String toLowerCase() 字符串中的所有内容转成小写
        // 2.String toUpperCase() 字符串中的所有内容转成大写
        String str = "abCDefGHJktyM";
        String lower = str.toLowerCase();
        String upper = str.toUpperCase();
        System.out.println("lower = " + lower);
        System.out.println("upper = " + upper);

        // 3.char[] toCharArray() 字符串转成字符数组
        char[] ch = str.toCharArray();
        System.out.println(ch);

        // 4.byte[]  getBytes() 字符串转成字节数组 (查询编码表),平台(操作系统)默认字符集
        String s = "呵呵你好";
        byte[] bytes = s.getBytes("gbk");
        for (int i = 0; i < bytes.length; i++) {
            System.out.println(bytes[i]);
        }

        // 5.static String valueOf(任意类型参数) 参数转成字符串对象
        int i = 1;
        String strI = String.valueOf(i);
        System.out.println(strI+1);
    }
(4) String 类的比较方法
  • int compareTo(String str) 字符串之间的比较,谁大谁小,按照字典顺序(自然顺序)(也就是 abcde… 的顺序)
    public static void main(String[] args) {
        stringMethod();
    }

    /**
     *  String 类的字符串的比较方法,字典顺序
     */
    public static void stringMethod(){
        // int compareTo(String str) 字符串之间的比较,谁大谁小,按照字典顺序(自然顺序)(也就是 abcde... 的顺序)
        String str1="abc";
        String str2="bbc";
        // 对象 str1 调用方法 compareTo 参数传递 str2
        /**
         *  返回值是 int
         *  返回的是负数,调用者小
         *  返回的是整数,调用者大
         *  返回的数零,就两者相等
         *  从前往后比较一旦比出大小就不再向后进行
         */
        int i=str1.compareTo(str2);
        System.out.println("i = " + i);
    }
(5) String 类的方法:去空格、替换、切割
  • String trim() 去掉字符串两边空格,中间空格不去掉
  • String replace(String oldString,String newString) 替换字符串
  • String[] split("规则字符串") 对字符串进行切割
    public static void main(String[] args) {
        stringMethod();
    }
    /**
     *  String类的方法 去空格,替换,切割
     */
    public static void stringMethod() {
        // 1. String trim() 去掉字符串两边空格,中间空格不去掉
        String str = "  abc  def       ";
        System.out.println(str);
        str = str.trim();
        System.out.println("str = " + str);

        // 2. 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]);
        }

        // 3. String replace(String oldString,String newString)替换字符串
        String repStr = "how do you do";
        repStr = repStr.replace("o","N");
        System.out.println("repStr = " + repStr);
    }
(6) 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} 表示 a 只能出现3次
    • X{m,} X这个字符至少出现 m 次
    • X{m,n} X这个字符至少出现 m 次,不超过 n 次
    • X? X这个字符出现一次,或者一次也没有
    • X* X这个字符出现零次或者多次
    • X+ X这个字符出现至少一次

查阅 API 文档寻找更多用法

(7) 正则表达式的匹配功能:String 类的方法 matches()
    public static void main(String[] args) {
        stringMethod();
    }
    /**
     *  正则表达式检查手机号码是否合法
     *  开头必须是 1 ,长度固定为 11
     *  第二位 3、4、5、6、7、8、9
     *  第三位必须是数字
     */
    public static void stringMethod(){
        String tel="13800138000";
        // 定义正则的规则,也是字符串
        String regx="1[3-9][0-9]{9}";
        // 第一位限制为 1 、第二位是 3-9 、第三位到最后一位都是数字 0-9 随机,一共出现九次
        // 正则规则,和字符串校验
        // String 类的方法 matches()
        boolean matches=tel.matches(regx);
        System.out.println("matches = " + matches);

    }
    public static void main(String[] args) {
        stringMethod();
    }
   /**
     *  检查邮箱
     *  规则 :
     *  @ 字符 前面 : 可以是数组、字母、混合、下划线、位数先不限制
     *  @ 字符 后面 : 数组、字母、及 sina qq 126 1393 yahoo gmail 位数先不限制
     *  . 字符 固定 : com  cn org  edu gov 字母  位数放下
     */
	public static void stringMethod(){
    	String email = "shihehe@sina.com";
    	String reg = "[\\w]+@[a-z0-9]+(\\.[a-z]+)+"; 
    	// 在 Java 中‘ \ ’有转义的功能,所以要多写一个
    	// 用小括号括起来就是一组,一组重复出现,设置次数,实际出现要小于等于设置的次数
    	boolean b = email.matches(reg);
    	System.out.println(b);

	}
(8)String 类的方法 split() (支持正则的切割)
   public static void stringMethod(){
       public static void main(String[] args) {
        stringMethod();
    }
    
        String str = "as123d387654w5465fasfr234567sa";
        String[] strings = str.split("\\d+");  // 按照数字切割 “ + ” 表示至少出现一次
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }

        String ip = "192.....168.....35.121";
        String[] ipArray = ip.split("\\.+");  // 按照数字切割 “ . ” 表示至少出现一次
        for (int i = 0; i < ipArray.length; i++) {
            System.out.println(ipArray[i]);
        }
    }
(9)String 类的方法 replaceAll() (支持正则的替换)
	public static void stringMethod4(){
        String str = "as123d387654w5465fasfr234567sa";
        // 字符串中的所有数字,换成 #
        String repString = str.replaceAll("\\d+","#");  // 定义新字符串,因为原字符串不能改动
        System.out.println(repString);

		// 只替换第一个符合规则的字符
        String first =  str.replaceFirst("\\d+","#");
        System.out.println(first);
    }

6. StringBuilder 字符串构建器

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

(1) 引出 StringBuilder 类
String str1 = "a"; // 字符数组
String str2 = "b"; // 字符数组
String str3 = str + str2; // 字符数组

这样写占用内存,字符串使用效率低,为了压缩内存出现了 StringBuilder 字符串构建器

(2) StringBuilder 类的实现原理

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

String 类中 :    private final char[] value;
StringBuilder :  char[] value; // 其中的方法是缺省状态只有本包可以使用,但是提供了 public 方法,可以调用
  1. 字符序列是数组,Java 数组是定长的,一旦创建,长度固定 。
  2. 创建对象的时候,StringBuilder 中的数组的初始化长度为16个字符
  3. 出现无法容纳问题的时候, StringBuilder 自动的进行数组的扩容,新创建一个数组,并且是开始数组的两倍,新数组实现,原来数组的中元素复制到新的数组,并且原数组被内存废弃销毁。
    (复制数组也很耗资源,但是相对于多有很多数组内存来说,综合考虑 StringBuilder 类较好。)
  • 结论 : 无论怎么做字符串的操作,StringBuilder 内部永远只有一个数组

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

  • StringBuffer 是线程安全的类,运行速度慢,多线程的程序中使用。

这两个类的构造方法,和其他的方法都一模一样。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值