java 字符串详解

字符串(String)是一系列的字符(char)。例如“Hello”是5个字符。字符串是一个不可变的对象,也就是说一旦创建就不能被修改。

字符串的创建

字符串创建有两种方式:

  • 字符串字面量 String str1 = "Welcome";

    字符串是对象,虽然我们在这里没有用new创建对象,其实是编译器给我们做了这些操作。这种创建的字符串对象有一个特点,如果同样的对象如果存在了,就不会创建一个新的对象,而是指向了同样的对象。例如String str2 = "Welcome";,则str1和str2是指向了字符串池中同样的内存地址。

  • new创建字符串 String str1 = new String("Welcome");
    用new关键字创建的字符串每次都会创建一个新的对象。

字符串池

注意点:String str = new String("World"); 会产生几个对象? 如果字符串池里面没有“World”对象,会在字符串池里面生成一个对象,然后再生成一个字符串对象,str指向这个对象;如果字符串池里面已经有了“World”对象,则只会生成一个对象,str指向这个对象。

String常用方法

字符串某个位置的字符 charAt(int index)

参数的索引从0开始,到str.length() - 1 为止。 如果不在这个范围则会抛出IndexOutOfBoundsException异常。

String str = "Hello world!";
str.charAt(0);  // H
str.charAt(1);  // e

字符串是否相等比较 == && equals(Object obj) && equalsIgnoreCase(String string)

==是内存的地址的比较;equals首先会用==比较,比较区分字符串的大小写,equalsIgnoreCase也会先用会用==比较,但是不区分大小写。

String str1 = "Hello world!";
String str2 = "Hello World!";

System.out.println(str1 == str2); // false
System.out.println(str1.equal(str2)); // false
System.out.println(str1. equalsIgnoreCase(str2)); // false

字符串大小比较 compareTo(String string): && compareToIgnoreCase(String string)

compareTo会用每个字符的Unicode进行比较,如果第一个字符串比第二个字符串大就返回正数,否则返回负数,如果一样则返回0。

String str1 = "Hello world!";
String str2 = "Hello World!";

System.out.println(str1.compareTo(str2)); // w比W的Unicode编码大32 结果为32
System.out.println(str1.compareToIgnoreCase(str2)); // 不区分大小写则相等,结果为0

字符串的前缀 startsWith(String prefix) 子字符串的前缀 startsWith(String prefix, int offset)

String str = "Hello world!";
System.out.println(str.startsWith("Hello"));  // 子字符串(Hello world!)的前缀是(Hello) ---> true
System.out.println(str.startsWith("wor", 6)); // 子字符串(world!)的前缀是(wor) ---> true 

字符串的后缀 endsWith(String suffix)

String str = "Hello world!";
System.out.println(str.endsWith("world!"));  // 子字符串(Hello world!)的后缀是(world!) ---> true

是否含有某个字符串 contains(CharSequence s)

String str = "Hello world!";
System.out.println(str.contains("a")); // false

字符出现的位置 indexOf(int ch) && indexOf(int ch, int fromIndex) && lastIndexOf(int ch) && lastIndexOf(int ch, int fromIndex)

如果找到返回索引位置,没找到返回-1.

String str = "Hello world!";
        
// 从前完后找字符的位置
System.out.println(str.indexOf("o"));  // 4
System.out.println(str.indexOf("O"));  // -1
        
// 从某个位置开始从前往后找字符的位置
// 注意:需要注意索引依然是从字符串的0开始,不是从开始检索的位置开始
System.out.println(str.indexOf("o", 6)); // 7
        
// 从后往前找字符串的位置
System.out.println(str.lastIndexOf("o")); // 7
        
// 从某个索引位置开始从后往前找字符的位置
System.out.println(str.lastIndexOf("o", 6)); // 4

字符串出现的位置 indexOf(String str) && lastindexOf(String str)

String str = "Hello world!";
        
System.out.println(str.indexOf("llo"));     // 2
System.out.println(str.lastIndexOf("wor")); // 6

子串 substring(int beginIndex) && substring(int beginIndex, int endIndex)

beginIndex 不能小于0,endIndex不能大于最大索引值。且beginIndex必须小于等于endIndex。

String str = "Hello world!";
        
System.out.println(str.substring(6));    // 从索引6开始到最后 ---> world!
System.out.println(str.substring(6, 6)); // 从索引6开始到索引9 ---> wor

字符串拼接一 concat(String str)

System.out.println("Hello".concat(" ").concat("world!")); // Hello world!

字符串拼接二 join(CharSequence delimiter, CharSequence... elements)

这是一个静态方法,第一参数是分隔符,后面是多个字符串,用分隔符拼接起来

String str = String.join(" ", "This", "is", "a", "String"); // This is a String

字符的替换 replace(char oldChar, char newChar) && replace(CharSequence target, CharSequence replacement)

String str = "Hello world!";
// 把字符串中某个字符都替换成新的字符。
System.out.println(str.replace("o", "a")); // Hella warld!
// 把字符串中某个字符串都替换成新的字符串。
System.out.println(str.replace("llo", "")); // He world!

正则表达式的替换 replaceFirst(String regex, String replacement) && replaceAll(String regex, String replacement)

replaceAll 和 replaceFirst都是用正则表达式去匹配替换的;replace是直接字符串替换

String str = "Telephone is 15512345678";
System.out.println(str.replaceFirst("\\d", "*")); // Telephone is *5512345678
System.out.println(str.replaceAll("\\d", "*"));   // Telephone is ***********

大写 toUpperCase() && 小写 toLowerCase()

String str = "Hello world!";
        
System.out.println(str.toUpperCase()); // HELLO WORLD!
System.out.println(str.toLowerCase()); // hello world!

字符串复用和初始化 intern()

String str1 = "Hello world!"; // 此时或在字符串池中建立一个"Hello world!"字符串
String str2 = new String("Hello world!").intern();  // 先在字符串池找"Hello world!",找到就赋值给str2,没有找到就初始化一个新的赋值给str2
System.out.println(str1.equals(str2)); // 相同

是否是空字符串

String str = "";
System.out.println(str.isEmpty()); // true

字符串拆分 split(String regex, int limit) && split(String regex)

split的第一个参数regex是一个正则表达式,第二个参数是返回分割的子字符串的最大值。默认是传0,就是不限制个数,所有子字符串都返回。

String str = "2018/01/01";
        
String[] array = str.split("/");
for(int i = 0; i < array.length; i++) {
    System.out.println(array[i]); // 2018  01  01
}

字符串格式化 format(String format, Object... args)

String str1 = "Welcome";
String str2 = "Johnny";

// %1$s 代表参数1,%2$s 代表参数二,以此类推。。。
String formateStr = String.format("Format String is: %1$s and %1$s, %2$s", str1, str2);
System.out.println(formateStr);  // Format String is: Welcome and Welcome, Johnny
        
String formateStr2 = String.format("My String is %.6f", 12.12);
System.out.println(formateStr2); // My String is 12.120000

去掉收尾空格

String str = "  Welcome  ";
System.out.println(str.trim()); //Welcome 去掉了首位的空格

生成字符数组 char[] toCharArray()

String str = "Welcome";
char[] arr = str.toCharArray(); // ["W","e","l","c","o","m","e"]

根据字符数组生成字符串 copyValueOf(char[] data) && copyValueOf(char[] data, int offset, int count)

char[] data = {'a','b','c','d','e','f','g','h','i','j','k'};
String str1 = "Original1";
String str2 = "Original2";
        
str1 = str1.copyValueOf(data); // 取所有的数组元素
System.out.println("str1 after copy: " + str1); // str1 after copy: abcdefghijk
        
str2 = str2.copyValueOf(data, 5, 3); //从第5个索引开始,取3个数组元素
System.out.println("str2 after copy: " + str2); // str2 after copy: fgh

把其他的类型数据变成字符串 valueOf() 或者用构造函数new String()

public static String valueOf(boolean b): Used for converting boolean value to a String

public static String valueOf(char c): char to String

public static String valueOf(int i): int to String

public static String valueOf(long l): long to String

public static String valueOf(float f): float to String

public static String valueOf(double d): double to String

int i = 10; //int类型
float f = 10.10f; //float类型
long l = 111L; //long类型
double d = 2222.22; //double类型
char ch = 'A'; //char类型
char array[] = {'a', 'b', 'c'}; //char数组类型

//把int变成字符串
String str1 = String.valueOf(i); 
        
//把float变成字符串
String str2 = String.valueOf(f); 
        
//把long变成字符串g
String str3 = String.valueOf(l);
        
//把double变成字符串
String str4 = String.valueOf(d);
        
//把char变成字符串
String str5 = String.valueOf(ch);
        
//把char array变成字符串
String str6 = String.valueOf(array);

把字符串变成比特数组 byte[] getBytes()

String扩展

String && StringBuffer && StringBuilder

StringBuffer 和 StringBuilder 都可以认为是可变的字符串。但是他们之间有一个区别就是 StringBuffer 是线程安全的而StringBuilder不是线程安全的。所以如果多线程操作需要用StringBuffer,而单线程操作建议使用StringBuilder,因为它更高效。

String 与 StringBuffer 和 StringBuilder 的区别是 不可变。

StringBuilder builder = new StringBuilder("Hello ");
builder.append("World!");
System.out.println(builder.toString()); // Hello world!

字符串转成int Integer.parseInt() && Integer.valueOf()

需要保证字符串能转成整形,否则会抛出NumberFormatException异常。

System.out.println(Integer.parseInt("22"));
System.out.println(Integer.valueOf("22"));

int转成字符串 Integer.toString() && valueof() && format()

Integer.toString(22)

字符串转成dobule Double.parseDouble(String) && Double.valueOf(String)

需要保证字符串能转成dobule,否则会抛出NumberFormatException异常。

System.out.println(Double.parseDouble("22.22"));
System.out.println(Double.valueOf("22.22"));

dobule转成字符串 Double.toString() && valueof() && format()

Double.toString(22.22); 

字符串转成long Long.parseLong() && Long.valueOf(String)

System.out.println(Long.parseLong("22"));
System.out.println(Long.parseLong("22"));

long转成 字符串 Long.toString() && valueof() && format()

Long.toString(200)

字符串转成Boolean Boolean valueOf(String s)

Boolean bobj = Boolean.valueOf("false");

Boolean转成字符串 Boolean.toString(boolean b) && String.valueOf(boolean b) && format()

String str = Boolean.toString(false);

Date 和 String的相互转换

DateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        
String dateString = "02-04-2018 23:30:00";
Date todaysDate = new Date();
        
try {
    // 把字符串变成日期
    System.out.println(format.parse(dateString));
    // 把日期变成字符串
    System.out.println(format.format(todaysDate));
            
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容