String类

Java程序中的所有字符串字面值(如 "abc" )都是String的实例

字符串是常量(因为 String 对象是不可变的,所以可以共享)

字符串的本质是字符数组:private final char value[];

创建字符串常用的方式

public class CreateString {
public static void main(String[] args) {
// 直接定义字符串
String str1 = "虎老狮";
// new 字符串
String str2 = new String("Java");
// 字符数组→字符串
char[] arrChar = { 'A', 'n', 'd', 'y' };
String str3 = new String(arrChar);
// 字节数组→字符串
byte[] arrByte = { 97, 98 };
String str4 = new String(arrByte);
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
}
}

字符串的比较

public class 字符串比较 {
public static void main(String[] args) {
String s1 = "奎木狼";
String s2 = "奎木狼";
String s3 = new String("奎木狼");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
}
}

解析:

采用字面值创建的字符串存放在常量池中(constant pool),同样内容的字符串对象指向同一个字符串对象。

常量池中的字符串,无则创建,有则直接使用。

字符串常量池:

相当于缓存,可以使得程序运行更快

以前在方法区,JDK 1.7之后,移到堆内存区(暂时不理解Java虚拟机内存知识的话,这句话直接无视)

new String()在运行时创建字符串对象,不在常量池中,因此s3和s1、s2不是同一个对象。

关于使用==进行比较判断:

|--基本类型,数值比较(只要求值相等,类型可以不同)

|--引用类型,地址比较(只有指向同一个对象才返回true)

public class 双等号基本类型 {
public static void main(String[] args) {
int a = 97;
double b = 97.0;
char c = 'a';
System.out.println(a == b);// true
System.out.println(c == b);// true
}
}
equals方法

String类提供equals方法进行字符串比较。

看下这个方法的源码:

地址相等的时候,直接就判为相等。地址不相等时,长度不等的直接判为不相等;长度相等时,一个一个字符比较。

    public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

应用:

public class 字符串比较 {
public static void main(String[] args) {
String s1 = "奎木狼";
String s2 = "奎木狼";
String s3 = new String("奎木狼");
System.out.println(s1.equals(s3));
System.out.println(s3.equals("奎木狼"));// 不推荐,可能空指针异常
System.out.println("奎木狼".equals(s3));// 推荐
}
}

推荐使用字符串字面值调用equals方法,即使用"...".equals(...),因为引号中的字符串字面值一定不会为null,调用方法不会出现空指针异常。

但是很多时候,无法确定其是否为null(比如调用equals方法的对象是从别处传入的参数)。

如果不能确定调用equals的对象必不为null,就需要在调用之前先做null判断。

if (s3 != null) {
boolean equals = s3.equals(s2);
System.out.println(equals);
}

或者使用Objects类提供的equals方法进行比较。Objects类从JAVA 1.7开始提供,可以防止空指针异常。

		String s1 = "奎木狼";
String s2 = "奎木狼";
String s3 = new String("奎木狼");
boolean equals = Objects.equals(s2, s3);
System.out.println(equals);// true

更多字符串比较方法:
boolean equalsIgnoreCase(String anotherString) 判断字符串anotherString是否与当前字符串相等,忽略大小写形式
int compareTo(String anotherString) 根据ASCII码比较字符串anoterString和当前字符串的大小,比较方式类似于C语言中的strcmp函数
boolean startsWith(String prefix) 判断当前字符串是否以字符串prefix为开头
boolean endsWith(String suffix) 判断当前字符串是否以字符串suffix为后缀
public class Test字符串比较 {
public static void main(String[] args) {
String str1 = "ABC";
System.out.println(str1.equalsIgnoreCase("abc"));// equalsIgnoreCase比较重要
System.out.println(str1.compareTo("ABB"));// 1
System.out.println(str1.compareTo("ABC"));// 0
System.out.println(str1.compareTo("ABD"));// -1
System.out.println(str1.startsWith("AB"));// T
System.out.println(str1.endsWith("C"));// T
}
}

字符串变量重新赋值,其实原字符串内容不变,只是变量中引用的地址变了。

因此,后面讲的字符串拼接、替换、去空格等操作都会得到新的字符串。

public class 字符串变内容不变 {
// 说明:System.identityHashCode(Onject):不同对象,此结果必不同
public static void main(String[] args) {
String s1 = "黄袍怪";
System.out.println(System.identityHashCode(s1));
s1 = "奎木狼";// s1保存的是地址值,之前的字符串对象没变,只是s1的地址变了
System.out.println(System.identityHashCode(s1));
String s2 = "黄袍怪";
System.out.println(System.identityHashCode(s2));
}
}

字符串提取

char charAt(int index) 从指定位置提取单个字符,该位置由index(索引值)指定
String substring(int index) 提取从index指定的位置开始的部分字符串
String substring(int begin, int end) 提取 begin 和 end 位置之间的部分字符串
String concat(String str) 连接两个字符串,并新建一个包含调用字符串的字符串对象
String replace (char oldChar, char newChar) 将字符串中出现oldChar指定的字符全部替换为newChar指定的字符
replaceAll(String regex, String replacement) 将字符串中匹配regex的字符串全部都替换为replacement指定的字符
String trim() 去除字符串前后的空格,得到的是一个新的字符串。
public class Test提取字符串 {
public static void main(String[] args) {
String str1 = "《西游记》中,如来为什么要传经?";
String str2 = new String("普度众生,一个都不能放过!");
System.out.println("------------查找--------------");
int _index = 2;
char _c = str1.charAt(_index);
System.out.println("charAt " + _index + ":" + _c);
System.out.println("------------substring--------------");
String _subStr = str1.substring(_index);
System.out.println("substring(" + _index + "):" + _subStr);
int _begin = 2, _end = 9;
_subStr = str1.substring(_begin, _end);
System.out.println("substring(" + _begin + "," + _end + "):" + _subStr);
System.out.println("------------拼接--------------");
System.out.println("concat:" + str1.concat(str2));
System.out.println("String + String:" + str1 + str2);
System.out.println("------------替换--------------");
char oldC = '西', newC = '东';
String _newString = str1.replace(oldC, newC);
System.out.println("replace(" + oldC + "," + newC + ") :" + _newString);
String _tar = "记", _repl = "释厄转";
_newString = str1.replace(_tar, _repl);
System.out.println("replace(" + _tar + "," + _repl + "):" + _newString);
_newString = "tel:10086".replaceAll("\\d", "*");
System.out.println("replaceAll(数字→*):" + _newString);
System.out.println("------------去空格--------------");
String s = " A B C ".trim();
System.out.println("trim:【" + s + "】");
}
}

字符串转为其它格式

byte[] getBytes() 将字符串转为byte数组(即字符串在内存中保存的最原始的二进制形态)
char[] toCharArray() 将字符串转为字符数组,类似于C语言中字符串的保存形式
public class Test字符串转化 {
public static void main(String[] args) {
byte[] b;
b = "Hello Java".getBytes();
for (int i = 0; i < b.length; i++) {
System.out.print("【" + b[i] + " " + (char) b[i] + "】");
}
System.out.println("-------------------------");
char[] c;
c = "Hello Java".toCharArray();
for (int i = 0; i < c.length; i++) {
System.out.print(" " + c[i]);
}
}
}

字符串转为字符串数组形式(.split(...)):

public class StringSplit {
public static void main(String[] args) {
String[] sArr = "01,天魁星,呼保义,宋江".split(",");
for (String s : sArr) {
System.out.println(s);
}
}
}

StringBuiler和StringBuffer

StringBuiler/StringBuffer表示可变的字符序列(即可变的字符串)

使用“+运算符”连接字符串将创建新的字符串,频繁修改字符串时,一般使用StringBuilerh或StringBuffer类以提高效率。

public class StringB {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("诸");
sb.append("葛");
sb.append("孔");
sb.append("明");
System.out.println(sb.toString());
}
}

解析:String的值是final的,因此字符串底层的存储数组是不变的,每次append都创建对象。

private final char value[];

StringBuilder的值不是final的

char[] value;// 在抽象类AbstractStringBuilder中定义

StringBuilder类
构造方法() 构造方法:创建一个空的StringBuffer对象
构造方法(String str) 构造方法:根据字符串str的内容创建StringBuffer对象
append(x) 添加内容:类型不限
insert(int index, x) 插入:将x插入到索引为index的位置,x可以为任何类型的数据
delete(int start, int end) 删除:从start位置开始,直到end指定的索引位置
deleteCharAt(int index) 删除:index指定的索引处的字符
setCharAt(int index, char ch) 替换:使用ch指定的新值替换 index指定的位置上的字符
replace(int start, int end, String str) 替换:从start指定的位置开始替换,直到 end 指定的位置结束
reverse() 字符序列倒置
length() 长度
String toString() 转换为字符串类型
public class TestStringBuXXX {
static void m最常用方法() {
StringBuilder sb = new StringBuilder();
// 【.length()】
System.out.println("length():" + sb.length());
// 【.append()】
sb.append("ABC,");
sb.append(true);
// 【.toString()】
System.out.println("append():" + sb.toString());
// 链式编程:append方法返回的就是自身,可以继续append
sb.append("青狮").append("白象").append("大鹏鸟");
System.out.println(sb.toString());
// 【转置:.reverse()】
sb.reverse();
System.out.println("转置:" + sb.toString());
// 【清空:.setLength(0)】
sb.setLength(0);
System.out.println("清空:" + sb.toString());
}
static void m其它常用方法() {
StringBuffer sb = new StringBuffer("ABCDEFGHI");
System.out.println("---插入---");
sb.insert(2, "123");
System.out.println("|--insert():" + sb);
System.out.println("---删除---");
sb.delete(2, 2 + 3);
System.out.println("|--delete():" + sb);
sb.deleteCharAt(2);
System.out.println("|--deleteCharAt():" + sb);
System.out.println("---替换---");
sb.setCharAt(2, '*');
System.out.println("|--setCharAt():" + sb);
sb.replace(1, 1 + 4, "#@");
System.out.println("|--replace():" + sb);
}
public static void main(String[] args) {
m最常用方法();
m其它常用方法();
}
}

*StringBuffer和StringBuilder用法上一样,StringBuilder适用于单线程环境,效率较高。

*StringBuffer是JDK 1.5新增的。

例:回文

写一个方法,判断某句话是不是回文(英文不区分大小写)。

如:Able was I ere I saw Elba

如:假似真时真似假

public class 回文 {
public static void main(String[] args) {
String s = "Able was I ere I saw Elba";
check(s);
s = "假似真是真似假";
check(s);
}
static void check(String s) {
String sLower = s.toLowerCase();
System.out.println(sLower);
StringBuffer s2 = new StringBuffer(sLower);
s2.reverse();
System.out.println(s2);
if (sLower.equals(s2.toString())) {
System.out.println("是回文");
} else {
System.out.println("不是回文");
}
}
}

*扩展·MessageFormat

java.text.MessageFormat

import java.text.MessageFormat;
import java.util.Date; public class TestMessageFormat {
public static void main(String[] args) {
String template = "姓名:{0},年龄:{1},时间:{2}";
String s = MessageFormat.format(template, "陈玄奘", 28, new Date());
System.out.println(s);
System.out.printf("姓名:%s,年龄:%d,时间:%s", "陈玄奘", 28, new Date());
}
}

Java基础教程——String类的更多相关文章

  1. Java基础笔记-String类

    String 类(被final修饰) 字符串是一种特殊的对象,一旦字符串被初始化就不可以被改变了.(内容不变) 例如: String  s = “abc”; String  s1 = new Stri ...

  2. Java基础之String类

    String类 字符串是不可变的,对其做的任何改变,会生成一个对象,不会改变有原有对象. ==和equals() String s1 = "good"; String s2 = & ...

  3. Java基础教程——System类

    System类 java.lang.System类代表当前Java程序的运行平台. |-可以做输入输出,垃圾回收:(此处不讲) |-可以获取时间: |-可以获取环境变量: |-可以获取系统信息: |- ...

  4. Java基础教程——Object类

    Object类 Object类是Java所有类类型的父类(或者说祖先类更合适) <Thinking in Java(Java编程思想)>的第一章名字就叫"everything i ...

  5. Java 基础之 String 类

    String String 被声明为 final,因此不能被继承.(Integer 等包装类也不能被继承) 在 java8 中,String 内部使用 char 数组 来存储数据 public fin ...

  6. Java基础教程(10)--类

    一.声明类   你已经见过了以如下方式定义的类: class MyClass { // field, constructor, and method declarations }   上面是声明类的最 ...

  7. Java基础笔记-String类2

    StringBuffer 特点: 是字符串缓冲区. 是一个容器,其长度可变,可以操作添加多个数据类型. 最后通过toString方法变成字符串. 被final锁修饰,因此不能被继承. 存储: 方法1: ...

  8. Java基础教程——File类、Paths类、Files类

    File类 File类在java.io包中.io代表input和output,输入和输出. 代表与平台无关的文件和目录. 可以新建.删除.重命名,但不能访问文件内容. File类里的常量: impor ...

  9. Java基础教程——BigDecimal类

    BigDecimal类 float.double类型的数字在计算的时候,容易发生精度丢失. 使用java.math.BigDecimal类可以解决此类问题. 前面讲过Math类,现在的BigDecim ...

随机推荐

  1. U137971 公司搬迁 - 并查集 奇偶性

    题目描述 因为人员规模扩大,T公司准备搬到新的写字楼去,写字楼分为A座和B座,n名不同工号的员工x(p1,p2,p3...pn) 按照下面两个规则确定在A座或者B座进行办公:(1)如果工号为x的员工在 ...

  2. 使用MQTT协议的4G DTU模块具有什么优势

    什么是MQTT协议 要了解使用MQTT协议的4G DTU模块具有哪些优势,首先我们需要了解什么是MQTT协议,MQTT协议最早是IBM开发的一个即时通讯协议,它的主要是为大量计算能力有限且工作在低带宽 ...

  3. pandas模块常用函数解析之Series(详解)

    pandas模块常用函数解析之Series 关注公众号"轻松学编程"了解更多. 以下命令都是在浏览器中输入. cmd命令窗口输入:jupyter notebook 打开浏览器输入网 ...

  4. python爬虫中的requests模块

    Requests: 让 HTTP 服务人类 一.简介 虽然Python的标准库中 urllib 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests ...

  5. java常用类——包装类

    八种基本数据类型对应八种包装类和它们的继承关系 基本数据类型 对应的包装类 boolean Boolean byte Byte short Short int Integer long Long ch ...

  6. Java Spring Cloud服务间调用

    A服务是用户服务,B服务某个需求需要用户信息,而B服务无法连接用户的数据库(分库),需要让A服务查询用户信息. 在B服务写一个接口去调用A服务的某个请求 /** * 访问A服务 */ @FeignCl ...

  7. kafka的基本安装与使用

    kafka的基本安装与使用 1.上官网下载tar包 2.解压 3.运行zookeeper 4.运行kafka服务器 5.创建topic 6.发送消息 7.监听消息 1.上官网下载tar包 https: ...

  8. 【杂谈】JS相关的线程模型整理

    1.JS是单线程吗? 是的,到目前为止,JS语言没有多线程的语法,它的执行引擎只支持单线程,也就是一个JavaScript进程内只有一个线程. 2.事件循环什么? 事件循环就是执行线程不断的从队列中取 ...

  9. Flink系列(0)——准备篇(流处理基础)

    Apache Flink is a framework and distributed processing engine for stateful computations over unbound ...

  10. Docker 运行 SQL Server 容器映像

    随着.Net Core迭代,大家也都用上了Linux用上了Docker.跟.Net经常配套使用的SQL SERVER以前一直是windows only,但是从SQL Server 2017开始已经支持 ...