1、相同又不同的字符串

String str1 = new String("String");
String str2 = "String";
String str3 = "String";
System.out.println(str2 == str1); //false
System.out.println(str2 == str3); //true
5
 
1
String str1 = new String("String"); 
2
String str2 = "String";
3
String str3 = "String";
4
System.out.println(str2 == str1); //false
5
System.out.println(str2 == str3); //true

如上,我们说String是引用数据类型,那么为什么这里有三个对象,str1和str2的结果是false,而str2和str3为true,表明它们俩最终指向的是同一对象呢?

这要从字符串的创建方式来说明,使用new是每次创建一个新的对象,而用赋值的方式,实际上先搜寻常量池是否有可用,有则直接给予,否则新建。所以问题来了,什么是字符串常量池?

字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能,所以JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化:
  • 为字符串开辟一个字符串常量池,类似于缓存区
  • 创建字符串常量时,首先坚持字符串常量池是否存在该字符串
  • 存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中

所以上面str2和str3实际上都是常量池中“String”的引用,自然完全相同,比对结果为true。

有一道经典的面试题:
String str = new String(“abc”) 创建多少个对象?
//所以,如果常量池中没有"abc",则创建了2个对象,一个放在常量池,一个放在堆;否则创建一个对象和一个引用
2
 
1
String str = new String(“abc”) 创建多少个对象?
2
//所以,如果常量池中没有"abc",则创建了2个对象,一个放在常量池,一个放在堆;否则创建一个对象和一个引用

所以变化一下:
String str1 = new String("A"+"B") ; 会创建多少个对象? 

str1:
字符串常量池:"A","B","AB" : 3个
堆:new String("AB") :1个
引用: str1 :1个
总共 : 5个
7
 
1
String str1 = new String("A"+"B") ; 会创建多少个对象? 
2

3
str1:
4
字符串常量池:"A","B","AB" : 3个
5
堆:new String("AB") :1个
6
引用: str1 :1个
7
总共 : 5个

简单总结:
  • 单独使用""引号创建的字符串都是常量,编译期(保存在.class文件中)就已经确定存储到常量池中
  • 使用new String("")创建的对象会存储在堆中,是运行期新创建的
  • 使用只包含常量的字符串连接符如"aa" + "aa"创建的也是常量,编译期就能确定,已经确定存储到常量池中
  • 使用包含变量的字符串连接符如"aa" + str1创建的对象是运行期才创建的,存储在堆中

而之所以能实现这些,也是有基础的:
  • 字符串本质上是不可变的(所谓的字符串连接无非是新建字符串,更改指向,而不是修改原有),不用担心数据冲突进行共享
  • 运行时实例创建的全局字符串常量池中有一个表,总是为池中每个唯一的字符串对象维护一个引用,这就意味着它们一直引用着字符串常量池中的对象,所以,在常量池中的这些字符串不会被垃圾收集器回收

更多参考:



2、常用方法

2.1 String常用方法

返回长度
length() //返回字符串的长度
转换(替换)字符
toLowerCase() //转换字符串为小写(仅针对字符串中的字母进行变化)
toUpperCase() //转换字符串为大写(仅针对字符串中的字母进行变化)
repalce(char oldChar, char newChar) // 将字符串中所有oldChar字符替换为newChar字符 字符串函数替换后需要赋值给新的字符串,旧字符串不会改变也不会重新指向新字符串
repalceFirst(String regex, String replacement) // 用字符串replacement的内容替换当前字符串中遇到的第一个和字符串regex一致的子串,并返回新的字符串(字符串长度可以不同,不会顶替掉未要求替换的字符)
repalceAll(String regex, String replacement) // 用字符串replacement的内容替换当前字符串中遇所有和字符串regex一致的子串,并返回新的字符串(字符串长度可以不同,不会顶替掉未要求替换的字符)
valueOf(Object obj) //将某个对象的实例转换成字符串 return:if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned. (而对于基本数据类型,如int 1,则会转成"1")
提取字符
charAt(int index) //返回字符串的第index个位置的字符
substring(int beginindex) //返回从beginindex位置(包括该位置)开始到结尾的所有字符
substring(int beginindex, int endindex) //返回从beginindex位置(包括)开始到endindex(不包括)的所有字符
比较字符
compareTo(String anotherString) //字符串比较,返回值为前者减后者的二者差(两个字符串同时从左往右比对,差值为首个不同字符的ASCII码的差值,数字字符为ASCII码相减)两个字符串完全相同输出为0
equals(Object anObject) //比较两个字符串的内容是否相同(大小写敏感),是则返回true,否则返回false
equalsIgnoreCase(String anotherString) //比较两个字符串的内容是否相同(忽略大小写),是则返回true,否则返回false
regionMatches(int toffset, String other, int ooffset, int len) //比较本串从toffset(包含)开始的len个字符和other串从ooffset开始的len个字符是否一致,返回值为boolean型
starstWith(String prefix) //比较字符串是否以prefix开始,返回值为boolean型
endsWith(String suffix) //比较字符串是否以suffix结束,返回值为boolean型
matches(String reg) //某字符串是否匹配reg正则表达式
查找字符位置
indexOf(int ch) //返回某个字符在本字符串中第一次出现的位置,没有找到就输出-1
indexOf(String str) //返回某个字符串在本字符串中第一次出现的位置,没有找到就输出-1
indexOf(int ch, int fromIndex) //返回某个字符在字符串中从fromindex位置开始查找的第一次出现的位置,没有找到就输出-1
indexOf(String str, int fromIndex) //返回某个字符串在字符串中从fromindex位置开始查找的第一次出现的位置,没有找到就输出-1
lastIndexOf(int ch) //返回某个字符在本字符串中最后一次出现的位置,没有找到就输出-1
lastIndexOf(String str) //返回某个字符串在本字符串中最后一次出现的位置,没有找到就输出-1
lastIndexOf(int ch, int fromIndex) //返回某个字符在字符串中到fromindex位置开始查找的最后一次出现的位置,没有找到就输出-1
lastIndexOf(String str, int fromIndex) //返回某个字符串在字符串中到fromindex位置开始查找的最后一次出现的位置,没有找到就输出-1
contains(CharSequence s) //是否包含某个字符
连接字符串
concat(String str) //将参数中的字符串str连接到原字符串的后面
去掉空格
trim() //去掉字符串开头和结尾的空格并返回新字符串,注意,中间的空格不会去掉
35
 
1
返回长度
2
length()   //返回字符串的长度
3
转换(替换)字符
4
toLowerCase()   //转换字符串为小写(仅针对字符串中的字母进行变化)
5
toUpperCase()  //转换字符串为大写(仅针对字符串中的字母进行变化)
6
repalce(char oldChar, char newChar)  // 将字符串中所有oldChar字符替换为newChar字符 字符串函数替换后需要赋值给新的字符串,旧字符串不会改变也不会重新指向新字符串
7
repalceFirst(String regex, String replacement)  // 用字符串replacement的内容替换当前字符串中遇到的第一个和字符串regex一致的子串,并返回新的字符串(字符串长度可以不同,不会顶替掉未要求替换的字符)
8
repalceAll(String regex, String replacement)  // 用字符串replacement的内容替换当前字符串中遇所有和字符串regex一致的子串,并返回新的字符串(字符串长度可以不同,不会顶替掉未要求替换的字符)
9
valueOf(Object obj)   //将某个对象的实例转换成字符串 return:if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned. (而对于基本数据类型,如int 1,则会转成"1")
10
提取字符
11
charAt(int index)   //返回字符串的第index个位置的字符
12
substring(int beginindex)   //返回从beginindex位置(包括该位置)开始到结尾的所有字符
13
substring(int beginindex, int endindex)  //返回从beginindex位置(包括)开始到endindex(不包括)的所有字符
14
比较字符
15
compareTo(String anotherString)  //字符串比较,返回值为前者减后者的二者差(两个字符串同时从左往右比对,差值为首个不同字符的ASCII码的差值,数字字符为ASCII码相减)两个字符串完全相同输出为0
16
equals(Object anObject)   //比较两个字符串的内容是否相同(大小写敏感),是则返回true,否则返回false
17
equalsIgnoreCase(String anotherString)   //比较两个字符串的内容是否相同(忽略大小写),是则返回true,否则返回false
18
regionMatches(int toffset, String other, int ooffset, int len)  //比较本串从toffset(包含)开始的len个字符和other串从ooffset开始的len个字符是否一致,返回值为boolean型
19
starstWith(String prefix)   //比较字符串是否以prefix开始,返回值为boolean型
20
endsWith(String suffix)   //比较字符串是否以suffix结束,返回值为boolean型
21
matches(String reg)   //某字符串是否匹配reg正则表达式
22
查找字符位置
23
indexOf(int ch)   //返回某个字符在本字符串中第一次出现的位置,没有找到就输出-1
24
indexOf(String str)   //返回某个字符串在本字符串中第一次出现的位置,没有找到就输出-1
25
indexOf(int ch, int fromIndex)  //返回某个字符在字符串中从fromindex位置开始查找的第一次出现的位置,没有找到就输出-1
26
indexOf(String str, int fromIndex)  //返回某个字符串在字符串中从fromindex位置开始查找的第一次出现的位置,没有找到就输出-1
27
lastIndexOf(int ch) //返回某个字符在本字符串中最后一次出现的位置,没有找到就输出-1   
28
lastIndexOf(String str) //返回某个字符串在本字符串中最后一次出现的位置,没有找到就输出-1
29
lastIndexOf(int ch, int fromIndex)  //返回某个字符在字符串中到fromindex位置开始查找的最后一次出现的位置,没有找到就输出-1
30
lastIndexOf(String str, int fromIndex)  //返回某个字符串在字符串中到fromindex位置开始查找的最后一次出现的位置,没有找到就输出-1
31
contains(CharSequence s)  //是否包含某个字符
32
连接字符串
33
concat(String str)   //将参数中的字符串str连接到原字符串的后面
34
去掉空格
35
trim()  //去掉字符串开头和结尾的空格并返回新字符串,注意,中间的空格不会去掉

2.2 String的format

另外,String还有一个静态方法format,用于创建格式化的字符串,常用 format (String format, Object... args),指定字符串格式和参数,生成格式化后的新的字符串。

如示例:
public static void main(String[] args) {
String str=null;
str=String.format("Hi,%s", "王力");
System.out.println(str);
str=String.format("Hi,%s:%s.%s", "王南","王力","王张");
System.out.println(str);
System.out.printf("字母a的大写是:%c %n", 'A');
System.out.printf("3>7的结果是:%b %n", 3>7);
System.out.printf("100的一半是:%d %n", 100/2);
System.out.printf("100的16进制数是:%x %n", 100);
System.out.printf("100的8进制数是:%o %n", 100);
System.out.printf("50元的书打8.5折扣是:%f 元%n", 50*0.85);
System.out.printf("上面价格的16进制数是:%a %n", 50*0.85);
System.out.printf("上面价格的指数表示:%e %n", 50*0.85);
System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85);
System.out.printf("上面的折扣是%d%% %n", 85);
System.out.printf("字母A的散列码是:%h %n", 'A');
}
18
 
1
public static void main(String[] args) {  
2
    String str=null;  
3
    str=String.format("Hi,%s", "王力");  
4
    System.out.println(str);  
5
    str=String.format("Hi,%s:%s.%s", "王南","王力","王张");            
6
    System.out.println(str);                           
7
    System.out.printf("字母a的大写是:%c %n", 'A');  
8
    System.out.printf("3>7的结果是:%b %n", 3>7);  
9
    System.out.printf("100的一半是:%d %n", 100/2);  
10
    System.out.printf("100的16进制数是:%x %n", 100);  
11
    System.out.printf("100的8进制数是:%o %n", 100);  
12
    System.out.printf("50元的书打8.5折扣是:%f 元%n", 50*0.85);  
13
    System.out.printf("上面价格的16进制数是:%a %n", 50*0.85);  
14
    System.out.printf("上面价格的指数表示:%e %n", 50*0.85);  
15
    System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85);  
16
    System.out.printf("上面的折扣是%d%% %n", 85);  
17
    System.out.printf("字母A的散列码是:%h %n", 'A');  
18
} 

输出:
Hi,王力
Hi,王南:王力.王张
字母a的大写是:A
3>7的结果是:false
100的一半是:50
100的16进制数是:64
100的8进制数是:144
50元的书打8.5折扣是:42.500000 元
上面价格的16进制数是:0x1.54p5
上面价格的指数表示:4.250000e+01
上面价格的指数和浮点数结果的长度较短的是:42.5000
上面的折扣是85%
字母A的散列码是:41
13
 
1
Hi,王力  
2
Hi,王南:王力.王张  
3
字母a的大写是:A   
4
3>7的结果是:false   
5
100的一半是:50   
6
100的16进制数是:64   
7
100的8进制数是:144   
8
50元的书打8.5折扣是:42.500000 元  
9
上面价格的16进制数是:0x1.54p5   
10
上面价格的指数表示:4.250000e+01   
11
上面价格的指数和浮点数结果的长度较短的是:42.5000   
12
上面的折扣是85%   
13
字母A的散列码是:41 

转换符说明如下:
转换符     说明     e.g.    
%s     字符串类型     "mingrisoft    "
%c     字符类型     'm'    
%b     布尔类型     true    
%d     整数类型(十进制)     99    
%x     整数类型(十六进制)     FF    
%o     整数类型(八进制)     77    
%f     浮点类型     99.99    
%a     浮点类型(十六进制)     FF.35AE    
%e     指数类型     9.38e+5
%g     通用浮点类型 
%h     散列码    
%%     百分比类型    
%n     换行符    
%tx     日期与时间类型


2.3 String的spilt

spilt可以将一个字符串分割为子字符串,然后将结果(子串的数组)作为字符串数组返回。

stringObj.split( separator,[limit] )
  • separator 必填,分隔符,支持正则表达式
  • limit 可选,该值用来限制返回数组中元素的个数

使用时注意以下几点:
  • 如果用“.”作为分隔的话,必须是如下写法:String.split("\\."),这样才能正确的分隔开,不能用String.split(".");
  • 如果用“|”作为分隔的话,必须是如下写法:String.split("\\|"),这样才能正确的分隔开,不能用String.split("|"); “.”和“|”都是转义字符,必须得加"\\";
  • 如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“a=1 and b =2 or c=3”,把三个都分隔出来,可以用String.split("and|or");

2.4 String和char[]

字符串转换为字符数组:
//将当前字符串中一部分复制到指定参数dst数组中去,并从dstBegin处开始存放
void getChars(int srcBegni, int srcEnd, char[] dst, int dstBegin) //初始化一个字符数组,长度和字符串长度相等
char[] toCharArray()
5
 
1
//将当前字符串中一部分复制到指定参数dst数组中去,并从dstBegin处开始存放
2
void getChars(int srcBegni, int srcEnd, char[] dst, int dstBegin)
3

4
//初始化一个字符数组,长度和字符串长度相等
5
char[] toCharArray()

字符数组转字符串,调用字符串的构造方法:
String(char[] value)

String(char[] value, int offset, int count)
x
 
1
String(char[] value)
2

3
String(char[] value, int offset, int count)


3、StringBuffer和StringBuilder

字符串的本质是不可变的,但是如果我们需要频繁地用到字符串的变动更改,就要用到StringBuffer,称之为字符串缓冲对象。实际上,诸如str1+str2这样的操作,也是将两者转换为StringBuffer来进行操作的。

常见构造函数为 new SringBuffer(String str)

StringBuilder是一个和StringBuffer类似的字符缓冲区,与StringBuffer兼容,然而:
  • StringBuffer在一个时候只能让一个线程去访问它,线程安全
  • StringBuilder是非线程安全的,所以单线程的话,StringBuilder的速度更快


[07] String字符串的更多相关文章

  1. [18/12/07]String 字符串

    一.基础概念 1. String类又称作不可变字符序列. 2. String位于java.lang包中,Java程序默认导入java.lang包下的所有类. 3. Java字符串就是Unicode字符 ...

  2. Java String字符串/==和equals区别,str。toCharAt(),getBytes,indexOf过滤存在字符,trim()/String与StringBuffer多线程安全/StringBuilder单线程—— 14.0

    课程概要 String 字符串 String字符串常用方法 StringBuffer StringBuilder String字符串: 1.实例化String对象 直接赋值  String str=& ...

  3. [CareerCup] 1.3 Permutation String 字符串的排列

    1.3 Given two strings, write a method to decide if one is a permutation of the other. 这道题给定我们两个字符串,让 ...

  4. 03-Java String字符串详解

    1.Java字符串String A.实例化String字符串:直接赋值(更合理一些,使用较多).使用关键字new. B.String内容的比较 // TODO Auto-generated metho ...

  5. C++学习38 string字符串的增删改查

    C++ 提供的 string 类包含了若干实用的成员函数,大大方便了字符串的增加.删除.更改.查询等操作. 插入字符串 insert() 函数可以在 string 字符串中指定的位置插入另一个字符串, ...

  6. C++学习37 string字符串的访问和拼接

    访问字符串中的字符 string 字符串也可以像字符串数组一样按照下标来访问其中的每一个字符.string 字符串的起始下标仍是从 0 开始.请看下面的代码: #include <iostrea ...

  7. java String字符串——进度1

    String字符串    在JAVA中提供了多种创建字符串对象的方法,这里介绍最简单的两种,    第一种是直接赋值,    第二种是使用String类的构造方法:    如下所示:    Strin ...

  8. 关于String字符串反转

    这是网上看到的一篇java面试题中的问题: 问题是: 如何将一个String字符串反转. String str = "1234567"; int length = str.leng ...

  9. JavaScript的内置对象(Date日期+string字符串)基础语法总结

    1.Date日期对象可以储存任意一个日期,并且可以精确到毫秒数(1/1000 秒). 1)定义一个时间对象 : var Udate=new Date(); //注意:使用关键字new,Date()的首 ...

随机推荐

  1. 设计模式(7)--Bridge(桥接模式)--结构型

    1.模式定义: 桥接模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥接模式的用意是“将抽象化(Abstraction)与实现化(Impleme ...

  2. fineui webform

    基于 jQuery 的专业 ASP.NET WebForms/MVC 控件库

  3. Python第一天---第一个Python程序

    1.我的环境是windows下,需要安装notepad++,安装Python2,配置环境变量(百度下可以见) 2.打开cmd窗口-----输入I:  [输入要在哪个磁盘存储python代码(我的在I: ...

  4. Integer陷阱(0~127和其他 数值相等对象比较)

    Integer 类在对象中包装了一个基本类型 int 的值. 有一个陷阱存在,经常出现在面试题中,情况如下面代码 public class IntegerDemo { public static vo ...

  5. MySql_5-7安装教程

    MySql_5-7安装教程... --------------------------------- 安装过成参考的文档: 参考网址:http://jingyan.baidu.com/article/ ...

  6. 后台生成EXCEL文档,自定义列

    后台生成EXCEL文档,自定义列 //response输出流处理 //设置编码.类型.文件名 getResponse().reset(); getResponse().setCharacterEnco ...

  7. Andrew Ng机器学习课程笔记--week8(K-means&PCA)

    Unsupervised Learning 本周我们讲学习非监督学习算法,会学习到如下概念 聚类(clustering) PCA(Principal Componets Analysis主成分分析), ...

  8. Python爬取糗事百科

    import urllib import urllib.request from bs4 import BeautifulSoup """     1.抓取糗事百科所有纯 ...

  9. 向GitHub 提交你的源代码

    之前的这篇文章「Git入门篇」相信大家都已经对 Git 的基本操作熟悉了,但是这篇文章只介绍了对本地 Git 仓库的基本操作,今天我就来介绍下如何跟远程仓库一起协作,教你们向 GitHub 上提交你们 ...

  10. asp.net mvc 4 项目升级到 asp.net mvc5

    一.开始 1.打开或新建asp.net mvc 4项目 2.修改 global.asax文件 原: WebApiConfig.Register(GlobalConfiguration.Configur ...