JavaSE学习值之--String类(三)

简介: JavaSE学习值之--String类(三)

JavaSE学习值之--String类(二)+https://developer.aliyun.com/article/1413506

7.字符串截取

从当前字符串某个索引位置处进行截取

String str = "helloworld";
        System.out.println(str.substring(5));// 输出world
        System.out.println(str.substring(0, 5));// 输出hello java中的区间都是左闭右开的

注意事项:

1. 索引从0开始

2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

8.其他操作方法

1.trim方法:

代码示例:

String str = "            hello            world               !!!!!!!!!";
        System.out.println(str.trim());

注意:

1.trim方法只能去除字符串左右两边的空格,中间的空格无法删除

2.trim方法其实在搜索引擎中经常出现,比如你故意在搜索时在前面添加了一大堆的空格,而你在搜索的时候,浏览器会自动把字符前面的所有空格进行删除,这就是调用了trim方法

8.字符串的不可变性

 String类型的数据是一种不可改变的数据类型,来看她的定义

1.这张图能反应很多信息:

1.String类被final修饰,代表不能被其他类继承

2.字符串实际上是存储在Value数组之中的,value也是一种引用类型

3.value数组被private修饰,代表无法在类外使用该数组,也就证明该数组的内容无法改变,也就是字符串的内容无法改变

一个误区:

 很多人说String类无法改变是因为value数组被final修饰,这是错误的,因为value数组被final修饰,只能说明value不能指向其他的引用,但是其所指向的对象是可以改变的(类似于const char*)

final int[] arr = {1,2,3,4,5};
        arr[0] = 10000;
        System.out.println(Arrays.toString(arr));

2.所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

StringBuilder也是与字符串相关的一个类,其中有一个append方法,用于字符串的追加

可以发现,在对字符串s进行追加时,实际上是又重新创建了一个字符串,使这个字符串为两个字符串append之后的结果,最后再将这个字符串重新赋值给s

二.StringBuilder和StringBuffer的介绍

前言:

 由于stirng的不可改变性,对于字符串的操作有了一定的限制,为了更加方便地操作字符串,引入两个新的类:StringBuilder和StringBuffer,这两个类的基本用法一致

一.StringBuilder

常见方法总结:

1.append--》字符串追加
//StringBuilder是一个类,必须先进行实例化对象
        StringBuilder str = new StringBuilder("hello");
        StringBuilder str2 = str;
        // 利用append进行追加  可追加字符,数字,字符串
        str.append(' ');
        str.append(123);
        str.append("world");
        str.append('!');
        System.out.println(str);

注意:

1.append方法的存在大大提高了新建字符串的效率,因为append方法在执行的时候是直接在位于缓冲区的字符数组之后添加字符的,并没有新建临时对象,减少了内存的不必要开辟和释放

2.可直接打印StringBuilder类的对象,因为其内部重写了toString方法

2.setCharAt(int index, char ch)-->将index位置的字符重置为ch
StringBuilder str = new StringBuilder("hello");
        str.setCharAt(0,'!');
        str.setCharAt(1,'!');
        str.setCharAt(2,'!');
        System.out.println(str);

3.insert(int offset, String str) -->在offset位置插入:八种基类类型 & String类型 & Object类型数据
StringBuilder str = new StringBuilder("hello");
        // insert方法
        // 并没有删除原位置的字符,而是在其之前插入另一个数据
        str.insert(0,'!');
        System.out.println(str);// !hello
        str.insert(6,"world");
        System.out.println(str);// !helloworld
        str.insert(0,123456);
        System.out.println(str);// 123456!helloworld

注意: insert方法并没有删除原位置的字符,而是在其之前插入另一个数据

4.deleteCharAt(int index)--》删除index位置字符
StringBuilder str = new StringBuilder("hello");
        System.out.println(str.deleteCharAt(0));// ello
        System.out.println(str.deleteCharAt(0));// llo
        // delete 删除指定区间内的所有字符
        StringBuilder str2 = new StringBuilder("hello");
        System.out.println(str2.delete(0, 2));// llo
5.replace(int start, int end, String str)--》将指定区间的字符串设置为str
StringBuilder str = new StringBuilder("hello!!!!");
        str.replace(1,6,"world");
        System.out.println(str);// hworld!!!
6.StringBuffer reverse()-->倒置字符串
StringBuilder str = new StringBuilder("hello!!!!world");
        System.out.println(str.reverse());// dlrow!!!!olleh

这是一个非常有用 的方法,在很多刷题网站中都有倒置字符串的实现,通过S听Builder自带的reverse方法可以快速实现!!!

源码:

public AbstractStringBuilder reverse() {
        boolean hasSurrogates = false;
        int n = count - 1;
        for (int j = (n-1) >> 1; j >= 0; j--) {
            int k = n - j;
            char cj = value[j];
            char ck = value[k];
            value[j] = ck;
            value[k] = cj;
            if (Character.isSurrogate(cj) ||
                Character.isSurrogate(ck)) {
                hasSurrogates = true;
            }
        }
        if (hasSurrogates) {
            reverseAllValidSurrogatePairs();
        }
        return this;
    }
7.toString方法-->以字符串(String)类型返回

String和StringBuffer不能直接赋值,必须通过StringBuffer的toString方法才能转换

StringBuilder str = new StringBuilder("hello!!!!world");
//        String str2 = str;// err
        String newstr = str.toString();
        System.out.println(newstr);// hello!!!!world

StringBuilder和StringBuffer也包含String类型中常见的方法,如indexOf,charAt,substring,length等方法,其用法和String类基本一致,此处不再详细阐述

总结:

String类是一个非常常用的类,要掌握其包含的常见方法的使用,深入理解String不能被改变和继承的原因;同时为了解决String类的一些缺陷,引入了两个新的类 StringBuilder和StringBuffer,这两个类可以看作String类的更高效的版本,其中有很多方法与String类重合,但也有很多自己独有的,非常有效的方法,了解这些方法会大大提高我们的开发效率!!!

三.再谈String类

1.字符串常量池

 呃呃,笔者经过进一步的学习又了解到了关于String类的相关知识,在这里进行更多的补充

先来看一下String的源码

在Java中String是一个类,每个String对象都有两个属性  value和hash ,value就是存储的值,hash就是对象对应的hash值

再来看下述代码

String s1 = "hello";
        String s2 = "hello";
        String s3 = new String("hello");
        String s4 = new String("hello");;
        System.out.println(s1 == s2);// true
        System.out.println(s3 == s4);// false

为什么s1和s2就相等呢?对象的比较不是根据对象的地址进行判断的么?在这里,引入一个概念--字符串常量池

 在Java中,所有被""引起来的都叫做字符串常量,所有的字符串都是存储到Java中一个名叫”字符串常量池“的存储区域中,但是官方并没有这个概念,而是使用一个叫做StringPool的方法将字符串常量存储起来,而StringPool的底层其实是StringTable,它是由哈希表实现的(使用c++编写)。

1.String s1 = "hello";这句代码实际上是将hello存储到StringTable之中,建立了对应的映射关系

2.String s2 = "hello";在为s2进行赋值时,会先在StringTable中判断hello是否存在,如果存在就不再重复放,如果不存在,将值存入;(hashTable的特性)

3.hello此时已经存在于StringTable之中,不再存入,而是直接从表中获取数据,也就是说s1和s2拿到的数据的地址是相同的!!!

而对于s3,s4来说,他们是通过new来实例化一个新的对象,则必然在内存中重新开辟一块内存,他们的地址不相同

2.intern方法

先来看下面代码

char[] arr = new char[] {'a','b','c'};
        String s1 = new String(arr);
        String s2 = "abc";
        System.out.println(s1 == s2);// false

分析:

 运用我们前面学习过的知识很容易判断

再来看下面代码

char[] arr = new char[] {'a','b','c'};
        String s1 = new String(arr);
        s1.intern();
        String s2 = "abc";
        System.out.println(s1 == s2);// true

为什么就输出true呢?intern方法是什么?

 intern方法就是将引用存入到常量池之中,intern方法是native的,底层是用c/c++写的

目录
相关文章
|
4月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
85 0
|
7月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
155 11
|
7月前
|
Java
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、"+"操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
164 9
|
7月前
|
存储 JavaScript Java
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化
100 1
|
11月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
312 2
|
12月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
297 2
|
12月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
95 1
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
146 0
java基础(13)String类
|
12月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
232 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
String类-知识回顾①
这篇文章回顾了Java中String类的相关知识点,包括`==`操作符和`equals()`方法的区别、String类对象的不可变性及其好处、String常量池的概念,以及String对象的加法操作。文章通过代码示例详细解释了这些概念,并探讨了使用String常量池时的一些行为。
String类-知识回顾①

热门文章

最新文章