String 类
[TOC]
String 类
概述
- String 是一种非常特殊的类,代表字符串,Java 程序中的所有字符串字面值,例如"abc"都作为 String 类的实例实现;
- String 是一个 final 类, 他的底层是一个 byte 类型的 final 数组,代表不可变的字符序列。字符串是常量,用双引号引起来表示,他们的值在创建之后不能更改;
- String 实现了 Serializable 接口、表示字符串是支持序列化的,实现了 Comparable 接口,表示 String 类型的字符可以比较大小;
实例化方式:
两种实例化方式
方式一:通过字面量定义的方式
String s = "abc132";
是一种非常特殊的形式,这里暂且叫他形式赋值(字面量) 其在 Java 中被叫做直接量,跟 new 有着本质的区别 ,他是 Java 中唯一一个不需要 new 就产生的对象,本方法产生的数据存放在方法区的常量池中;
方式二:通过 new + 构造器的方式
- new 出来的对象通常会被放在堆里 而 形式赋值产生的直接量在创建的时候 会在 JVM 内部发生字符串扣留 -->1.先查看常量池中是否有内容相同的字符串,若有 ,则将其直接指向常量池中已有的字符串 ,偌常量池中没有声明的该字符串,则创建一个字符串将其放入常量池中;
String s = "abc"; s += "def"; // 这里也是会直接重新创建一个内存区域用来存储连接过的字符串 //当调用 String.replace 来修改字符串内容时,也会直接创建一个新的内存区域用来存储
若两种方式创建的方法不同,但是内容相同,那么 new 出来的 String 对象里的属性指向的还是同一个方法区里的常量池中的数据的地址;
String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); String s4 = new String("abc"); System.out.println(s1 == s2); //true System.out.println(s1 == s3); //false System.out.println(s3 == s4); //false
上述例子中,如果有变量参与进来,那么其将会被定义在堆空间当中,在堆空间当中 new 一个变量;
但是常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
intern( ):在调用 ”ab”.intern() 方法的时候会返回 ”ab”,但是这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用;
String 类常会用到的方法
String s1 = "Hello World"; System.out.println("原版" + s1); //原版 Hello World
- 获取字符串长度--> length
System.out.println(s1.length()); //11
取指定索引位置的字符-->charAt(int index )
```java System.out.println(s1.charAt(0)); //H System.out.println(s1.charAt(6)); //W System.out.println(s1.charAt(7)); //o ```
判断字符串是否为空 返回布尔类型-->isEmpty( )
```java System.out.println(s1.isEmpty()); //false ```
转换大小写**--> **toLowerCase( )、toUpperCase( )
String s2 = s1.toLowerCase();//小写 //新创建 System.out.println(s1); //Hello World System.out.println(s2); //小写 hello world String s3 = s1.toUpperCase(); System.out.println(s3);//大写 HELLO WORLD
- 忽略前导和尾部空白-->trim( )
String s4 = " hello wo r l d "; String s5 = s4.trim(); System.out.println("--" + s4 + "--");//-- hello wo r l d -- S ystem.out.println("--" + s5 + "--"); //--hello wo r l d--
equals()比较字符串内容
equalsIgnoreCase 忽略大小写比较
```java String s6 = "hello world"; System.out.println(s6.equals(s1));//false System.out.println(s6.equalsIgnoreCase(s1)); //true ```
连接字符 concat
```java String s7 = s1.concat("哈哈哈"); System.out.println(s7); //Hello World哈哈哈 ```
compareTo 调用者-被调用者 这里 a-b
```java String a = "a"; String b = "b"; System.out.println(a.compareTo(b)); // a -b = -1 会涉及到字符串排序 ```
提取字符串
```java String s8 = s1.substring(0, 5); // 左闭右开区间 System.out.println(s8); // Hello System.out.println(s1); // Hello World ```
endWith 是否以指定字符串结尾
```java boolean ld = s1.endsWith("ld"); System.out.println(ld); //true ```
startWith 是否以指定字符串开始
```java boolean hell = s1.startsWith("Hell"); System.out.println(hell); //true ```
字符串是否包含字符
boolean hello = s1.contains("Hello"); System.out.println(hello); //true
indexOf 查找指定字符第一次出现的位置的索引
int wo = s1.indexOf("Wo"); // 有则返回索引 无则返回 -1 System.out.println(wo); // 6 int lo = s1.indexOf("lo", 2); System.out.println(lo); //3
lastIndexOf 从后往前找
replaceAll 把字符串中的数字替换成,如果开头和结尾有“,”的话就去掉
```java String s9 = "2heladfoj545542dada1"; String s = s9.replaceAll("\\d", ",").replaceAll("^,|,$", ""); //正则表达式 System.out.println(s9); //2heladfoj545542dada1 System.out.println(s); //heladfoj,,,,,,dada ```
判断字符串是否全部由数字组成
```java boolean matches = s1.matches("\\d+"); System.out.println(matches); //false ```
判断是否为某地区被电话
```java String tel = "0349-1234567"; boolean matches1 = tel.matches("0349-\\d{7,8}");//后面跟了 7、8 位数字 System.out.println(matches1); //true ```
split 切分
String -> char [ ]
```java char[] chars = s1.toCharArray(); System.out.println(Arrays.toString(chars)); ```
将 char 型数组转为 String
```java char[] ch1 = new char[]{'h', 'e', 'l', 'l', 'o'}; String ss = new String(ch1); System.out.println(ss); ```
String 转换为 byte[ ]
```java String str = "abc123汉字"; byte[] bytes = str.getBytes();//默认采用UTF-8 System.out.println(Arrays.toString(bytes)); byte[] gbks = str.getBytes("gbk"); //采用gbk编码格式 System.out.println(Arrays.toString(gbks)); ```
StringBuilder
在Java9之后,String、StringBuilder、StringBuffer 等的底层实现都是字节数组 byte[] value;
三者区别:
String、StringBuffer、StringBuilder 的区别
String:底层 final 的,不可变的字符序列
StringBuffer:底层非 final 的,可变的字符序列,线程安全,但是效率偏低
StringBuilder:底层非 final 的,可变的字符序列,效率高,但是线程不安全
上述三者的共同点是:java8 之前包括 8,他们的底层实现都是的字符数组
char [ ],在java9以及之后的版本中改为了 byte [] 数组;
StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类
三者的效率:
StringBuilder > StringBuilder > String
- 操作少量的数据: 适用 String
- 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
- 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer
扩容问题:StringBuffer 类无参构造创建一个长度大小为 16 的 char 型数组,如果添加不下,那么就需要将原来的数组空充为原来的 2 倍 + 2,同时会将原有的数组复制到新的数组当中去
建议使用 StringBuffer 类中的有参构造 指定大小 容量 StringBuffer(int capacity)
常用基本功能
- 增 append
- 删 delete
- 改 replace
- 查 indexOf
- 插 insert
- 长度 length
- 遍历 toString( ) \ for 循环 +charAt( )
互相转换:
String --> StringBuffer、StringBuilder :直接调用他们的构造器 String 类型传参即可,反之亦然
也可以通过 toString 来转换
public class StringBufferTest { public static void main(String[] args) { StringBuffer s1 = new StringBuffer("abc"); System.out.println("长度为:" + s1.length());//3 System.out.println(s1); s1.append("def"); System.out.println("长度为:" + s1.length());//6 s1.insert(2, "123");//在指定位置(非索引)之后插入指定字符串 System.out.println(s1); s1.replace(2, 5, ""); //替换指定位置之后的指定字符串 左闭右开区间 System.out.println(s1); s1.delete(3, 4); //删除指定位置之后的字符串 左闭右开区间 System.out.println(s1); s1.reverse(); //当前字符串翻转 System.out.println(s1); //indexOf() 查询字符第一次出现位置的索引 //返回索引区间内的一个子字符串 左开右闭 String substring = s1.substring(0, 3); System.out.println(substring); String s3 = "abc"; StringBuffer stringBuffer = new StringBuffer(s3); System.out.println(stringBuffer); StringBuffer stringBuffer1 = new StringBuffer("def"); String s = stringBuffer1.toString(); System.out.println(s); } }
练习
上例子!
String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); String s4 = new String("abc"); System.out.println(s1 == s2); // true System.out.println(s1 == s3); // false System.out.println(s3 == s4); // false
拼接字符串
String s1 = "javaEE"; String s2 = "hadoop"; String s3 = "javaEEhadoop"; String s4 = "javaEE" + "hadoop"; String s5 = s1 + "hadoop"; String s6 = "javaEE" + s2; String s7 = s1 + s2; System.out.println(s3 == s4); // true 常量和常量的拼接结果会在常量池中,且常量池中不会存在内容相同的常量值 System.out.println(s3 == s5); // false 只要有一个值是来自于变量的,那么拼接结果就会存在于堆中,在堆空间中 new 一块空间出来 System.out.println(s3 == s6); // false System.out.println(s3 == s7); // false System.out.println(s5 == s6); // false System.out.println(s5 == s7); // false System.out.println(s6 == s7); // false
- 10个有关String的面试问题
- ScannerTest-------double string
- apache StringUtils isNotEmpty isNotBlank的区别
- 557. Reverse Words in a String III
- 从Long.ValueOf("String")与Long.parseLong("String")看JAVA包装类的封箱与拆箱
- C#控制台基础 枚举类型与int,string相互转换
- HttpRequest.QueryString 属性
- Java String.getBytes();解决utf-8乱码
- Codeforces 1144 E. Median String
- String to Integer (atoi)
- 浮点型转string
- 关于String与Integer类型比较问题
- 2017北京师范大学ACM校赛 J Just A String (KMP)
- 主题:【总结】String in Java
- wchar_t*,wchar_t,wchat_t数组,char,char*,char数组,std::string,std::wstring,CString 以及system("command")
- 请编写一个JavaScript函数 parseQueryString,它的用途是把URL参数解析为一个对象
- expected number,sequence,or string.map evaluated instead of freemarker.template.smplehash
- 909422229_DOM4J读取XML文件与解析StringXML
- JavaSE7 switch_case_String实现验证
- c++的字符串char与string相互转化,以及string的,切割,替换字符,字符串拼接方法