8、String类的特点及使用

JDK_API文档由下面几部分组成:
(1)类的定义以及相关的继承结构
(2)类的简短说明
(3)类的成员组成
(4)类所提供的构造方法
(5)类所提供的普通方法
(6)类的成员,构造方法,普通方法的详细说明
deprecated标记表示不再建议使用。

String对象的两种实例化方式

1.String是字符串类,下面将类的角度与内存关系分析其作用:
(1)直接赋值String value_name = "字符串"

public class Demo {
    public static void main(String[] args) {
        String str = "Hello World !"; // 直接赋值
        System.out.println(str);
    }
}

(2)构造方法public String (String str);

public class Demo {
    public static void main(String[] args) {
        String str = new String("Hello World !");
        System.out.println(str);
    }
}

字符串比较

1.判断两个int数据是否相等:

public class Demo {
    public static void main(String[] args) {
        int x = 10;
        int y = 10;
        System.out.println(x == y); // true
    }
}

使用==判断String对象是否相等:

public class Demo {
    public static void main(String[] args) {
        String strA = "Hello";
        String strB = new String("Hello");
        String strC = strB;
        System.out.println(strA == strB); // false
        System.out.println(strA == strC); // false
        System.out.println(strB == strC); // true
    }
}

对上述代码进行内存分析:
8、String类的特点及使用
由内存分析可知,String对象使用==比较时,比较的是对象的栈内存地址的值
2.要比较字符串的内容,应使用String类中的方法public boolean equals(String str)

public class Demo {
    public static void main(String[] args) {
        String strA = "Hello";
        String strB = new String("Hello");
        String strC = strB;
        System.out.println(strA.equals(strB)); // true
        System.out.println(strA.equals(strC)); // true
    }
}

开发中,字符串比较应用equals(String str).
3.章节例题:==equals(String str)的区别
==是关系运算符,用于判断数值相等,当用于String对象时对比的是两个对象的栈内存地址的值;
equals(String str)是String类的方法,用于比较字符串内容。

String常量是匿名对象

1.编程语言中没有字符串概念,很多语言使用字符数组描述字符串。Java开发由于离不开字符串的使用,便创造了字符串,但不属于基本数据类型,而是将字符串作为String类的匿名对象。
范例:验证字符串是匿名对象

public class Demo {
    public static void main(String[] args) {
        String str = "Hello";
        System.out.println("Hello".equals(str));
    }
}

2.直接赋值的方式相当于给匿名对象设置了对象名,区别是String匿名对象是系统自动生成,不需要由用户实例化.

public class Demo {
    public static void main(String[] args) {
        String input = null; // 假设该内容是用户输入的
        if (input.equals("hello")){
            System.out.println("Hello World !");
            // 报错,NullPointerException
        }
    }
}

为预防用户输入错误导致input为null,而后调用equals(),出现空指针异常,应使用如下代码:

public class Demo {
    public static void main(String[] args) {
        String input = null; // 假设该内容是用户输入的
        if ("hello".equals(input)){
            System.out.println("Hello World !");
        }
    }
}

使用上述代码将不会出现空指针异常,因此在判断用户输入的内容是否符合预期时,应将指定字符串放在equals()前

两种实例化方式的区别

1.直接赋值
直接赋值就是给字符串匿名对象设置对象名。
此时内存中会开辟堆内存,并且有一块栈内存指向堆内存:
8、String类的特点及使用
观察下列代码:

public class Demo {
    public static void main(String[] args) {
        String strA = "hello";
        String strB = "hello";
        String strC = "hello";
        String strD = "world";
        System.out.println(strA == strB); // true
        System.out.println(strA == strC); // true
        System.out.println(strB == strC); // true
        System.out.println(strA == strD); // false
    }
}

由上述结果可知,strA,strB,strC都指向同一块堆内存:
8、String类的特点及使用
共享设计模式:JVM底层存在一个对象池,保存有对象。当使用直接赋值定义String对象时,会将该对象使用的匿名对象入池保存。而后如果有其他String对象也采用直接赋值方式且内容相同时,便不再开辟新的堆内存,而是引用对象池中已有的匿名对象。
2.构造方法实例化
使用构造方法定义String对象,就需要每次开辟新的堆内存。
8、String类的特点及使用
由内存分析可知,使用构造方法实例化时开辟了两块堆内存,并且其中一块会成为垃圾。

public class Demo {
    public static void main(String[] args) {
        String strA = new String("hello");
        String strB = "hello";
        System.out.println(strA == strB); // false
    }
}

除了内存的浪费外,使用构造方法定义的String对象,其内容不会保存在对象池中,因为每次开辟的都是新的堆内存。如果希望开辟的新的的堆内存也进入对象池保存,可以使用public String intern()手工入池。

3.章节小题:String对象两种定义方式的区别
· 直接赋值只开辟一块堆内存,且会自动保存在对象池中,以便下次使用;
· 构造方法赋值会开辟两块堆内存,其中一块会成为垃圾,不会自动入池,但可以使用”intern()”手工入池。

字符串内容不可改变

public class Demo {
    public static void main(String[] args) {
        String str = "Hello";
        str += " World";
        str += " !!!";
        System.out.println(str);
    }
}

对上述代码进行内存分析:
8、String类的特点及使用
分析后可知,字符串内容并未改变(Java规定String对象内容不可变),字符串内容的变动实际是引用关系的变化,每次都会出现垃圾。因此字符串内容不要频繁改动。

String类常用方法(字符与字符串)

很多语言利用字符数组描述字符串,Java中String类的方法也有相似方法:

No. 方法名称 类型 描述
1 public String (char[] value) 构造 将字符数组变为String类对象
2 public String (char[] value ,int offset,int count) 构造 将部分字符数组变为String对象
3 public char charAt (int index) 普通 返回指定索引对应的字符信息
4 public char[] toCharArray() 普通 将字符串以字符数组的形式返回

范例:取出指定索引的字符

public class Demo {
    public static void main(String[] args) {
        String str = "Hello";
        char c = str.charAt(0);
        System.out.println(c); // H
    }
}

范例:将字符串转大写

public class Demo {
    public static void main(String[] args) {
        String str = "hello";
        char [] data = str.toCharArray(); // 字符串转为字符数组
        for (int x = 0; x < data.length ; x++) {
            data[x] -= 32; // 小写编码 - 32 = 大写编码
        }
        // 将字符数组变为字符串
        System.out.println(new String(data)); // HELLO
        // 将部分字符数组变为String对象
        System.out.println(new String(data, 1, 2)); // EL
    }
}

范例:判断一个字符换是否为纯数字
思路:对字符串整体进行判断是无法实现的,但是可以将字符串转为字符数组,判断每一个字符是否为数字。

public class Demo {
    public static void main(String[] args) {
        String str = "3146017052";
        if (isNumber(str)) {
            System.out.println("字符串全部由数字组成");
        } else {
            System.out.println("字符串不是全部由数字组成");
        }
    }

    // 定义判断字符串是否由数字组成的方法
    public static boolean isNumber(String temp) {
        // 首先将字符串变为字符数组
        char[] data = temp.toCharArray();
        // 一一比较字符
        for (int x = 0; x < data.length; x++) {
            if (data[x] > '9' || data[x] < '0') {
                return false;
            }
        }
        // 全部为数字则返回true
        return true;
    }
}

建议:返回值为boolean的方法命名为isXxx

String类常用方法(字节与字符串)

字节使用byte描述,一般用于数据传输或编码转换。String提供了将字符数组变为字节数组的方法。

No. 方法名称 类型 描述
1 public String (byte[] bytes) 构造 将字节数组变为字符串
2 public String (byte[] bytes ,int offset,int length) 构造 将部分字节数组变为字符串
3 public byte[] getBytes (String charsetName) throws UnsupportedEncodingException 普通 进行编码转换
4 public byte[] getBytes() 普通 将字符串变为字节数组

范例:字符串与字节数组的转换

public class Demo {
    public static void main(String[] args) {
        String str = "helloworld";
        byte [] data = str.getBytes(); // 将字符串转为字节数组
        for (int x = 0; x < data.length ; x++) {
            data[x] -= 32; // 将小写字母转为大写字母
        }
        System.out.println(new String(data)); // HELLOWORLD
        System.out.println(new String(data,5,5)); // WORLD
    }
}

String类常用方法(字符串比较)

No. 方法名称 类型 描述
1 public boolean equals(String anotherString) 普通 进行内容判断,区分大小写
2 public boolean equalsIgnoreCase(String anotherString) 普通 进行内容判断,不区分大小写
3 public int compareTo (String anotherString) 普通 判断两个字符串的大小(按照字符编码),返回值为0,1,-1

范例:equals()判断

public class Demo {
    public static void main(String[] args) {
        String strA = "Hello";
        String strB = "hello";
        System.out.println(strA.equals(strB)); // false,说明区分大小写
    }
}

范例:equalsIgnoreCase()判断

public class Demo {
    public static void main(String[] args) {
        String strA = "Hello";
        String strB = "hello";
        System.out.println(strA.equals(strB)); // false,说明区分大小写
        System.out.println(strA.equalsIgnoreCase(strB)); // true,说明不区分大小写
    }
}

范例:compareTo()

public class Demo {
    public static void main(String[] args) {
        String strA = "Hello";
        String strB = "hello";
        System.out.println(strA.compareTo(strB)); // -32
        if (strA.compareTo(strB) > 0){
            System.out.println("大于");
        } else if (strA.compareTo(strB) == 0){
            System.out.println("两个字符串相等");
        } else {
            System.out.println("小于");
        }
    }
}

只有String对象才能进行大小判断。

String类常用方法(字符串查找)

要判断指定内容的字符串是否存在于一个字符串中,可使用如下方法:

No. 方法名称 类型 描述
1 public boolean contains (String s) 普通 判断指定内容是否存在
2 public int indexOf(String s) 普通 由前向后查找指定字符串的位置,找到后返回首字母索引,未找到,返回-1。
3 public int indexOf(String s,int fromIndex) 普通 从指定索引由前向后查找指定字符串的位置,找到后返回首字母的索引。未找到,返回-1
4 public int lastindexOf(String s) 普通 由后向前查找指定字符串的位置,找到后返回首字母的索引,如果找不到,返回-1
5 public int lastindexOf(String s, int fromIndex) 普通 由后向前从指定位置查找指定字符串的位置,找到后返回首字母的索引,如果找不到,返回-1
6 public boolean startsWith (String prefix) 普通 判断是否以指定字符串开头
7 public boolean startsWith (String prefix,int toffset) 普通 从指定位置开始判断是否是以指定字符串开头
8 public boolean endsWith(String suffix) 普通 判断是否以指定字符串结尾

范例:查找字符串位置

public class Demo {
    public static void main(String[] args) {
        String str = "helloworld";
        // 返回满足条件的单词的首字母索引
        System.out.println(str.indexOf("world")); // 5,为w的索引
        // 从索引5开始查满足条件单词的索引
        System.out.println(str.indexOf("l",5)); // 8
        // 从后向前查
        System.out.println(str.lastIndexOf("l")); // 8
    }
}

在某些程序中,需要查找指定字符串是否存在,早期方法如下:

public class Demo {
    public static void main(String[] args) {
        String str = "helloworld";
        if (str.indexOf("world") != -1){
            System.out.println("该字符串存在");
        } else {
            System.out.println("该字符串不存在");
        }
    }
}

JDK1.5出现contains(),使用如下:

public class Demo {
    public static void main(String[] args) {
        String str = "helloworld";
        if (str.contains("world")) {
            System.out.println("该字符串存在");
        } else {
            System.out.println("该字符串不存在");
        }
    }
}

范例:开头或结尾判断内容

public class Demo {
    public static void main(String[] args) {
        String str = "helloworld";
        // 从开头开始查
        System.out.println(str.startsWith("he"));
        // 从索引2开始查找
        System.out.println(str.startsWith("ll",2));
        // 从结尾开始查找
        System.out.println(str.endsWith("ld"));
    }
}

String类常用方法(字符串替换)

No. 方法名称 类型 描述
1 public String replaceAll(String regex,String replacement) 普通 全部替换
2 public String replaceFirst(String regex,String replacement) 普通 替换首个满足条件的内容
public class Demo {
    public static void main(String[] args) {
        String str = "helloworld";
        // 替换所有
        String resultA = str.replace("l","_"); // he__owor_d
        // 只替换第一个
        String resultB = str.replaceFirst("l","_"); // he_loworld
        System.out.println(resultA);
        System.out.println(resultB);
    }
}

String类常用方法(字符串截取)

No. 方法名称 类型 描述
1 public String substring(int beginIndex) 普通方法 从指定索引截取到结尾
2 public String substring(int beginIndex,int endIndex) 普通方法 截取指定范围内的内容
public class Demo {
    public static void main(String[] args) {
        String str = "helloworld";
        // 从索引5开始截取直到结尾
        String resultA = str.substring(5); 
        // 截取索引5到8之间
        String resultB = str.substring(5,8); 
        System.out.println(resultA); // world
        System.out.println(resultB); // wor
    }
}

String类常用方法(字符串拆分)

No 方法名称 类型 描述
1 public String[] split (String regex) 普通方法 按照指定的字符串进行全部拆分
2 public String[] split (String regex,int limit) 普通方法 按照指定的字符串进行部分拆分,最后一个数组长度由limit决定

范例:全部拆分

public class Demo {
    public static void main(String[] args) {
        String str = "hello world";
        // 按照空格拆分单词
        String result[] = str.split(" ");
        for (int x = 0; x < result.length; x++) {
            System.out.println(result[x]);
            // 结果:hello
            // world
        }
    }
}

在拆分的时候,只写一个空字符串(""不是null),表示按照每一个字符进行拆分。

public class Demo {
    public static void main(String[] args) {
        String str = "hello world";
        // 按照空字符串拆分
        String result[] = str.split("");
        for (int x = 0; x < result.length; x++) {
            System.out.println(result[x]);
            // 结果:h e l l o w o r l d
        }
    }
}

范例:部分拆分

public class Demo {
    public static void main(String[] args) {
        String str = "hello world nihao mldn";
        // 把字符串按空格拆成3个,前2个拆完后,后面的不再按空格拆
        String result[] = str.split(" ",3);
        for (int x = 0; x < result.length; x++) {
            System.out.println(result[x]);
            // 结果:"hello" "world" "nihao mldn"
        }
    }
}

范例:IP地址拆分

public class Demo {
    public static void main(String[] args) {
        String str = "192.168.1.1";
        String result[] = str.split("\\.");
        for (int x = 0; x < result.length; x++) {
            System.out.println(result[x]);
            // 结果为:192 168 1 1
        }
    }
}

上述代码中,只用.无法拆分,当遇到这种拆分时,需要使用\\.进行转义后拆分。
范例:拆分“张三:20|李四:25|王五:23”

public class Demo {
    public static void main(String[] args) {
        String str = "张三:20|李四:25|王五:23";
        String result[] = str.split("\\|");
        for (int x = 0; x < result.length; x++) {
            String temp[] = result[x].split(":");
            System.out.println("姓名:" + temp[0] + ",年龄" + temp[1]);
        }
    }
}

String类其他方法

No. 方法名称 类型 描述
1 public String concat (String str) 普通方法 字符串连接
2 public String toLowerCase () 普通方法 把字符串转为小写
3 public String toUpperCase () 普通方法 把字符串转为大写
4 public String trim () 普通方法 去掉字符串中左右两边的空格,中间空格保留
5 public int length() 普通方法 取得字符串长度
6 public String intern () 普通方法 数据入池操作
7 public boolean isEmpty () 普通方法

范例:字符串连接

public class Demo {
    public static void main(String[] args) {
        String strA = "hello";
        String strB = strA + " world";
        String strC = "hello" + "world";
        String strD = "hello world";
        String strE = strA.concat(" world");
        System.out.println(strB == strC); // false
        System.out.println(strB == strD); // false
        System.out.println(strB == strE); // false
        System.out.println(strC == strD); // false
        System.out.println(strC == strE); // false
        System.out.println(strD == strE); // false
    }
}

范例:字符串进行大小写转换

public class Demo {
    public static void main(String[] args) {
        String str = "*Hello*";
        // 只转换小写字母
        System.out.println(str.toUpperCase()); // *HELLO*
        // 只转换大写字母
        System.out.println(str.toLowerCase()); // *hello*
    }
}

范例:去掉空格

public class Demo {
    public static void main(String[] args) {
        String str = " Hello World ";
        System.out.println("【" + str + "】"); // 【 Hello World 】
        System.out.println("【" + str.trim() + "】"); // 【Hello World】
    }
}

用户进行数据输入时,可能携带无用的空格,接收到这些数据后就要消掉这些无用的空格,这时候就用到了trim()
范例:取得字符串长度

public class Demo {
    public static void main(String[] args) {
        String str = "Hello World";
        System.out.println(str.length()); // 11
    }
}

某些情况要求用户输入的数据长度有限制,可以利用此方法判断。
范例:判断是否是空字符串

public class Demo {
    public static void main(String[] args) {
        String str = "";
        System.out.println(str.isEmpty()); // true
        System.out.println("".equals(str)); // true
    }
}

范例:实现首字母大写,其余字母小写

public class Demo {
    public static void main(String[] args) {
        String str = "hElLo";
        System.out.println(initcap(str)); // Hello
    }

    public static String initcap(String temp) {
        // 截取第一个字母,将其变为大写;截取首字母之后的字母将其变为小写
        return temp.substring(0, 1).toUpperCase() + temp.substring(1).toLowerCase();
    }
}