从0开始学Java(010)_String类的特点及使用

JDK_API

  • jdk_api文档由下面几部分组成:
    (1)类的定义以及相关的继承结构
    (2)类的简短说明
    (3)类的成员组成
    (4)类所提供的构造方法
    (5)类所提供的普通方法
    (6)类的成员,构造方法,普通方法的详细说明
    deprecated标记表示不再建议使用。
  • 由jdk_api可知
JDK1.8JDK1.9
String类保存的字符数组String类保存的是byte数组

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.直接赋值
直接赋值就是给字符串匿名对象设置对象名。
此时内存中会开辟堆内存,并且有一块栈内存指向堆内存:
在这里插入图片描述
观察下列代码:

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都指向同一块堆内存:
在这里插入图片描述
共享设计模式:JVM底层存在一个对象池,保存有对象。当使用直接赋值定义String对象时,会将该对象使用的匿名对象入池保存。而后如果有其他String对象也采用直接赋值方式且内容相同时,便不再开辟新的堆内存,而是引用对象池中已有的匿名对象。
2.构造方法实例化
使用构造方法定义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()手工入池。

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

String对象常量池

对象池用于实现数据的共享。在Java中对象池分为两种:

  • 静态常量池:程序在加载时会自动将此程序中保存的字符串、普通常量和类的方法信息等,全部分配
  • 运行时常量池:当程序加载之后,为内部的一些变量提供的常量池。
    静态常量池范例:
public class Demo {
    public static void main(String args[]) {
        String msg = "hello world";
        String msg2 = "hello" + " world";
        System.out.println(msg == msg2); // true
    }
}

由于msg和msg被赋予的是字符串常量,因此程序加载时会自动处理好相应的连接:即程序发现"hello world""hello" + " world"最终的内容是一致的,因此两者指向了同一个内存空间。
运行时常量池范例:

public class Demo {
    public static void main(String args[]) {
        String info = " world";
        String msg = "hello world";
        String msg2 = "hello" + info;
        System.out.println(msg == msg2); // false
    }
}

由于程序加载时,info是个变量,无法确定info的最终内容,所以程序无法判定msg和msg2最终的内容是否一致,无法进行自动连接。因此两者的内存空间不一致。

字符串内容不可改变

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

对上述代码进行内存分析:
在这里插入图片描述
分析后可知,字符串内容并未改变(Java规定String对象内容不可变),字符串内容的变动实际是引用关系的变化,每次都会出现垃圾。因此字符串内容不要频繁改动。

字符串比较

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

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

2.使用==判断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
    }
}

由内存分析可知,String对象使用==比较时,比较的是对象的栈内存地址的值

3.字符串内容比较应使用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).

章节例题:==equals(String str)的区别
==是关系运算符,用于判断数值相等。当该符号用于String对象比较时,比较的是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()前

String类常用方法

字符与字符串

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

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

字节与字符串

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

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

字符串比较

No.方法名称类型描述
1public boolean equals(String anotherString)普通进行内容判断,区分大小写
2public boolean equalsIgnoreCase(String anotherString)普通进行内容判断,不区分大小写
3public 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对象才能进行大小判断。

字符串查找

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

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

字符串替换

No.方法名称类型描述
1public String replaceAll(String regex,String replacement)普通全部替换
2public 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);
    }
}

字符串截取

No.方法名称类型描述
1public String substring(int beginIndex)普通方法从指定索引截取到结尾
2public 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
    }
}

字符串拆分

No方法名称类型描述
1public String[] split (String regex)普通方法按照指定的字符串进行全部拆分
2public 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]);
        }
    }
}

字符串格式化

JDK1.5之后,Java提供了格式化数据的操作,类似于利用占位符实现数据输出。常见的占位符有:字符串%s, 字符%c,整数%d,小数%f

No.方法名称类型描述
1public static String format(String format, Object… args)普通方法根据指定格式进行文本格式化显示
public class Demo {
    public static void main(String args[]) {
        String name = "Jack";
        int age = 10;
        double score = 98.5;
        System.out.println(String.format("Name: %s, Age: %d, Score: %5.2f", name, age, score));
    }
}

String类其他方法

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

范例:字符串连接

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();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值