字符串

从概念上讲,Java字符串就是Unicode字符序列。例如,字符串"Java\u2122"由5个Unicode字符Java组成。Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类,很自然地叫做String。每个双引号括起来的字符串都是String类中的一个实例

String e = "";  // an empty string
String greeting = "Hello"

子串

String类的substring方法返回字符串的子字符串。

语法

public String substring(int beginIndex)

或

public String substring(int beginIndex, int endIndex)

参数

  • beginIndex -- 起始索引(包括), 索引从 0 开始。
  • endIndex -- 结束索引(不包括)

例子

public class FirstSample {
public static void main(String[] args) {
String Str = "This is text"; System.out.print("返回值 :" );
System.out.println(Str.substring(4) ); // 从第4个索引开始到结束 System.out.print("返回值 :" );
System.out.println(Str.substring(4, 10) ); // 从第4个索引开始到第10个结束,不包括第10个
}
}

结果

返回值 : is text
返回值 : is te

现在我们知道了substring的用法,接下来看看源码

源码分析

    /**
* Returns a string that is a substring of this string. The
* substring begins at the specified {@code beginIndex} and
* extends to the character at index {@code endIndex - 1}.
* Thus the length of the substring is {@code endIndex-beginIndex}.
* <p>
* Examples:
* <blockquote><pre>
* "hamburger".substring(4, 8) returns "urge"
* "smiles".substring(1, 5) returns "mile"
* </pre></blockquote>
*
* @param beginIndex the beginning index, inclusive.
* @param endIndex the ending index, exclusive.
* @return the specified substring.
* @exception IndexOutOfBoundsException if the
* {@code beginIndex} is negative, or
* {@code endIndex} is larger than the length of
* this {@code String} object, or
* {@code beginIndex} is larger than
* {@code endIndex}.
*/
// 定义了substring方法,有两个参数beginIndex和endIndex
public String substring(int beginIndex, int endIndex) {
// 如果起始索引小于0,抛出异常
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
// 如果结束索引大于值的长度,抛出异常
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
// 子串的长度
int subLen = endIndex - beginIndex;
// 如果子串的长度小于0,抛出异常
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
// 如果起始索引等于0并且结束索引等于字符串的长度,那么返回字符串本身,否则创建一个新的字符串
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}

拼接

与绝大多数程序设计语言一样,Java语言允许使用+号连接(拼接)两个字符串。这个没什么说的。

但是要注意:当将一个个字符串与一个非字符串的值进行拼接时,后者会转换字符串。例如:

int age = 13;
String x = "jkc" + age;

结果是jkc13

如果我们需要把多个字符串放在一起,并用一个界定符分隔,可以使用静态join方法:

public class FirstSample {
public static void main(String[] args) {
System.out.print("返回值 :" );
System.out.println(String.join("/", "A", "B", "C", "D"));
}
}

结果

返回值 :A/B/C/D

join方法有两种重载方法,这里只介绍以下这一种

public static String join(CharSequence delimiter, CharSequence… elements)
  • delimiter:字符串分隔符
  • ...elements:指定的字符串

String.join("/", "A", "B", "C", "D")的意思就是用分隔符/将ABCD这4个字符串连接起来,结果自然就是A/B/C/D

不可变字符串

在Java中是不能修改Java字符串中的单个字符的,所以再Java文档中将String类对象称为是不可变的,如果真的想修改,可以提取想保留的子串,再与希望替换的字符拼接:

greeting = greeting.substring(0, 3) + "p!";

检测字符串是否相等

可以使用equals方法检测两个字符串是否相等,语法:

s.equals(t)

如果字符串s与字符串t相等,则返回true;否则,返回false。

要想检测两个字符串是否相等,而不区分大小写,可以使用equalsIsIgnoreCase方法。

"Hello".equalsIgnoreCase("hello");

注意:一定不要使用==运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否在同一个内存地址上。当然,如果字符串在同一个内存地址上,它们必然相等。但是,完全有可能将内容相同的多个字符串放置在不同的内存地址上。

public class FirstSample {
public static void main(String[] args) {
String greeting = "Hello";
System.out.println("变量greeting的内存地址为:" + System.identityHashCode(greeting));
System.out.println("hello的内存地址为:" + System.identityHashCode(greeting));
if (greeting == "Hello") {
System.out.println("同一个内存地址,相等");
}
String x = greeting.substring(0, 3);
System.out.println("变量x的内存地址:" + System.identityHashCode(x));
if (x == "Hel") {
System.out.println("内存地址不同");
}
}
}

如果虚拟机始终将相同的字符串共享,就可以使用==运算符检测是否相等。但实际上只有字符串字面量是共享的,而+substring等操作得到的字符串并不共享。因此,千万不要使用==运算符测试字符串的相等性,以免在程序中出现这种最糟糕的bug,看起来这种bug就像随机产生过的间歇性错误。

空串与Null串

空串""是长度为0的字符串。可以调用以下代码检查一个字符串是否为空:

if (str.length() == 0)

if (str.equals(""))

空串是一个Java对象,有自己的串长度(0)和内容(空)。不过String变量还可以存放一个特殊的值,名为null,表示目前没有任何对象与该变量关联。要检查一个字符串是否为null,要使用以下条件:

if (str == null)

有时要检查一个字符串既不是null也不是空串,这种情况下就需要使用以下条件:

if (str !=null && str.length() != 0)

首先要检查str不为null,如果在一个null值上调用方法,会出现错误。

String API

Java中的String类包含了50多个方法,接下来介绍一些最常用的方法

java.lang.String 1.0

  • char charAt(int index)

    返回给定位置的代码单元。除非对底层的代码单元感兴趣,否则不需要调用这个方法。
  • int codePointAt(int index)

    返回从给定位置开始的码点。
  • int offsetByCodePoints(int startIndex, int cpCount)

    返回从startIndex码点开始,cpCount个码点后的码点索引。
  • int compareTo(String other)

    按照字典顺序,如果字符串位于other之前,返回一个负数;如果字符串位于other之后,返回一个正数;如果两个字符串相等,返回0.
  • IntStream codePoints()

    将这个字符串的码点作为一个流返回。调用toArray将它们放在一个数组中
  • new String(int[] codePoints, int offset, int count)

    用数组中从offset开始的count个码点构造一个字符串。
  • boolean isEmpty()

    如果字符串为空,返回true
  • boolean equals(Object other)

    如果字符串与other相等,返回true
  • boolean equalsIgnoreCase(String other)

    如果字符串与other相等(忽略大小写),返回true
  • boolean startsWith(string prefix)

    判断字符串是否是以prefix前缀开始
  • boolean endsWith(String suffix)

    判断字符串是否是以suffix后缀开始
  • int indexOf(String str)
  • int indexOf(String str, int fromIndex)
  • int indexOf(int cp)
  • int indexOf(int cp, int fromIndex)

    返回与字符串str或码点cp匹配的第一个子串的开始位置。从索引0或fromIndex开始匹配。如果在原始字符串中不存在str,则返回-1
  • int lastIndexOf(String str)
  • int lastIndexOf(String str, int fromIndex)
  • int lastIndex(int cp)
  • int lastIndex(int cp, int fromIndex)

    返回与字符串str或码点cp匹配的最后一个子串的开始位置。从原始字符串末尾或fromIndex开始匹配。
  • int length()

    返回字符串代码单元的个数
  • int codePointCount(int startIndex, int endIndex)

    返回startIndexendIndex-1之间的码点个数

    String replace(CharSequence oldString, CharSequence newString)

    返回一个新字符串。这个字符串用newString代替原始字符串中所有的oldString。可以用StringStringBuilder对象作为CharSequence参数。
  • String substring(int beginIndex)
  • String substring(int beginIndex, int endIndex)

    返回一个新字符串。这个字符串包含原始字符串中从beginIndex到字符串末尾或endIndex-1的所有代码单元
  • String toLowerCase()
  • String toUppCase()

    返回一个新字符串。这个字符串将原始字符串中的大写字母改成小写,或者将原始字符串中的所有小写字母改成大写。
  • String trim()
  • String strip() 11

    返回一个新字符串。这个字符串将删除原始字符串头部和尾部小于等于U+0020的字符(trim)或空格(strip)。
  • String join(CHarSequence delimiter, CharSequence... elements)

    返回一个新字符串,用给定的定界符连接所有元素
  • String repeat(int count) 11

    返回一个字符串,将当前字符串重复count次

构建字符串

  有些时候,需要由较短的字符串构建字符串,例如,按键或来自文件中的单词。如果采用字符串拼接的方式来达到这个目的,效率会比较低。每次拼接字符串时,都会构建一个新的String对象,既耗时,又浪费空间。使用StringBuilder类就可以避免这个问题发生。

  如果需要用许多小段的字符串来构建一个字符串,那么应该按照下列步骤进行。首先,构建一个空的字符串构建器:

StringBuilder builder = new StringBuilder();

当每次需要添加一部分内容时,就调用append方法

builder.append("jkc");
builder.append("jkc2");
builder.append("jkc3");

在字符串构建完成时就调用toString方法,将可以得到一个String对象,其中包含了构建器中的字符序列。

String completedString = builder.toString();

下面的API包含了StringBuilder类中的重要方法

  • StringBuilder()

    构造一个空的字符串构建器
  • int length()

    返回构建器或缓冲器中的代码单元数量
  • StringBuilder append(String str)

    追加一个字符串并返回this
  • StringBuilder append(char c)

    追加一个代码单元并返回this
  • StringBuilder appendCodePoint(int cp)

    追加一个码点,并将其转换为一个或两个代码单元并返回this
  • void setCharAt(int i, char c)

    将第i个代码单元设置为c
  • StringBuilder insert(int offset, String str)

    offset位置插入一个字符串并返回this
  • StringBuilder insert(int offset, char c)

    offset位置插入一个代码单元并返回this
  • StringBuilder delete(int startIndex, int endIndex)

    删除偏移量从startIndexendIndex-1的代码单元并返回this
  • String toString()

    返回一个与构建器或缓冲器内容相同的字符串

零基础学Java(4)字符串的更多相关文章

  1. 零基础学Java第四节(字符串相关类)

    本篇文章是<零基础学Java>专栏的第四篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! String 本文章首发于公众号[编程攻略] 在Java中,我们经 ...

  2. 零基础学Java第三节(基本输入输出)

    本篇文章是<零基础学Java>专栏的第三篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] Java程序的命令行参数 我们可以 ...

  3. 零基础学Java第二节(运算符、输入、选择流程控制)

    本篇文章是<零基础学Java>专栏的第二篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 第一章 运算符 1.1 算术运算符的概述和用法 运算符 对常量和变 ...

  4. 零基础学Java第一节(语法格式、数据类型)

    本篇文章是<零基础学Java>专栏的第一篇文章,从本篇文章开始,将会连更本专栏,带领大家将Java基础知识彻底学懂,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! ...

  5. 零基础学Java,PayPal技术专家手把手带你入门

    在最权威的 TIOBE 编程语言排名榜单上,Java 常年稳居第一,可以说是世界上应用最为广泛的一门语言. 同时,在微服务.云计算.大数据.Android App 开发等领域,Java 也是当之无愧的 ...

  6. 零基础学Java第五节(面向对象一)

    本篇文章是<零基础学Java>专栏的第五篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] 类与对象 在哲学体系中,可以分为主 ...

  7. 零基础学Java第六节(面向对象二)

    本篇文章是<零基础学Java>专栏的第六篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] 继承 创建一个Person类 我们 ...

  8. 零基础学python-7.2 字符串常量

    1.单双引號字符串是一样的 >>> 'abc',"abc" ('abc', 'abc') >>> 当你的python照着上面的样例来写,这个时候 ...

  9. 零基础学python-7.7 字符串格式化方法(1)

    承接上一章节.我们这一节来说说字符串格式化的还有一种方法.就是调用format() >>> template='{0},{1} and {2}' >>> templ ...

  10. 零基础学python-7.6 字符串格式化表达式

    字符串格式化同意在一个单个的步骤中对一个字符串运行多个特定类型的替换 特别是给用户提示的时候,格式化很方便 实现方法: 1.格式化表达式,类似于c语音的printf 在表达式中,我们使用%二进制操作符 ...

随机推荐

  1. Ubuntu 下 Mariadb 数据库的安装和目录迁移

    Ubuntu 下 Mariadb 数据库的安装和目录迁移 1.简介 本文主要是 Ubuntu 下 Mariadb 数据库的安装和目录迁移,同样适用于 Debian 系统:Ubuntu 20.0.4 M ...

  2. Windows10 office 点击链接提示您的组策略阻止我们为您完成此操作。设置ChromeHTML也无效.

    问题: win10环境点击office 中的网络链接时  出现了如下报错(一般在卸载了系统预装的其他浏览器后出现问题) 解决方案: 1.设置默认浏览器(已经设置可跳过) 控制面板->设置小图标 ...

  3. ThinkPhP $map用法

    ThinkPHP内置了非常灵活的查询方法,可以快速的进行数据查询操作,查询条件可以用于CURD等任何操作,作为where方法的参数传入即可,下面来一一讲解查询语言的内涵.查询方式ThinkPHP可以支 ...

  4. python数据处理-matplotlib入门(2)-利用随机函数生成变化图形2

    鉴于上一篇中最后三个问题: 1.上述程序是否能进行优化(比如功能相同的) 2.创建三个3个实例,用了3个语句,能否建一个函数,只输入一个数n,就自动创建n个实例?同时,每个实例的num_times随机 ...

  5. 通过命令验证docker容器相当一个轻量级的Linux运行环境,且每个容器内都有一个属于自己的文件系统,容器之间相互隔离

    一.docker的三个重要概念 1.镜像:打包项目带上环境,即镜像 Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资源.配置等文件外,还包含了一些为运行时准备的配置参数.镜像 ...

  6. lab_1 清华大学ucore bootload启动ucore os(预备基础知识+实验过程)

    实验1 :bootload启动ucore os 1.0实验内容: lab1中包含一个bootloader和一个OS.这个bootloader可以切换到X86保护模式,能够读磁盘并加载ELF执行文件格式 ...

  7. 实战 | 一文带你读懂Nginx反向代理

    一个执着于技术的公众号 前言 在前面的章节中,我们已经学习了nginx基础知识: 给小白的 Nginx 10分钟入门指南 Nginx编译安装及常用命令 完全卸载nginx的详细步骤 Nginx 配置文 ...

  8. Linux系统inodes资源耗尽问题

    1 inodes介绍 Linux系统下文件数据储存在"块"中,文件的元信息,例如文件的创建者.文件的创建日期.文件的大小等.这种储存文件元信息的区域就叫做inode,中文译名为&q ...

  9. 《Java编程思想》读书笔记(二)

    三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...

  10. 拯救一切强迫症 - 读《编写可维护的 JavaScript》(一)

    拯救一切强迫症 - 读<编写可维护的 JavaScript>(一) 本文写于 2020 年 4 月 24 日 我在小学的时候就有接触过编程,所以读大一的时候 C 语言还算是轻车熟路.自然会 ...