Java基础之String类

String类

字符串是不可变的,对其做的任何改变,会生成一个对象,不会改变有原有对象。

==和equals()

String s1 = "good";
String s2 = "good";
if (s1 == s2) {} // true 这种直接把字符串赋值给对象的情况,是存储在常量池里的,指向同一个地址
// another example
String s1 = "good";
String s2 = new String("good");
if (s1 == s2) {} // false, new出来的对象存储在堆内存,和存放在常量池指向的不是同一个地址

// 当然,两个都是new出来的对象,即使他们内容相同,用“==”来比较地址也是不同的
// String类覆盖了equals()方法,比较的是字符串的内容。故一般不用==来比较
// 无论是以上那种情形,只要内容是"good",就是true
if (s1.equals(s2)) {}
  

像Integer一类的由基本数据类型封装成的对象,也是覆写了equals方法的,和String类一样也是比较的内容。但是在使用==比较的时候有些区别。

Integer a = new Integer(6);
Integer b = new Integer(6);
// 可以像如上方式实例化,也可像下面这样,下面这种方式称为自动装箱(从int -> Integer)
Integer c = 6;
Integer d = 6;
Integer e = 128;
Integer f = 128;
if (c==d) {} // true
if (e == f) {} // false,why?
  • 自动装箱时候,当使用==比较,仅限于闭区间[-128, 127],两个内容相同的对象地址也是相同的,超出这个范围,地址就不同了,比较结果false
  • 当然equals方法比较的还是内容,不管哪种方式实例化,只要内容相同,比较结构就是true。

compareTo()

字符串的比较用str1.compareTo(str2),实际上是String类实现了Comparable<String>并覆盖了compareTo方法,对于字符串中每个字符,按照字典序进行比较。关于其返回值:比较到第一个不相同的字符是,结束比较,返回这两个字符的ASCII码数值之差;若相同则比较下一个,以此类推,如果比较完较短字符串的所有字符还是相等,这时开始比较字符串长度,返回两个字符串长度的差值。

String s1 = "abc"; 
String s2 = "abcd"; 
String s3 = "abcdfg"; 
String s4 = "1bcdfg"; 
String s5 = "cdfg"; 
System.out.println( s1.compareTo(s2) ); // -1 (前面相等,s1长度小1) 
System.out.println( s1.compareTo(s3) ); // -3 (前面相等,s1长度小3) 
System.out.println( s1.compareTo(s4) ); // 48 (第一个字符就不等,结束比较,"a"的ASCII码是97,"1"的的ASCII码是49,所以返回48) 
System.out.println( s1.compareTo(s5) ); // -2 ("a"的ASCII码是97,"c"的ASCII码是99,所以返回-2)

注意:String s1 = ""String s2 = null无论是用equals()还是==比较都是flase。因为s1表示该字符串内容为空,长度为0,指向某个地址。而s2没有绑定任何地址,是一个空指针,更谈不上有长度(调用length()报错)。

String类一些常用方法

一般来说,实例化String类String str = "good"就可满足。但有时候使用String str = new String("...")能实现额外的功能。

char[] a = {97, 98, 99}; // 和这个等价char[] a = {'a', 'b', 'c'};
String str = new String(a); // 可以传入字符数组,打印abc
// 还能指定偏移量和字符个数,1表示从数组下标1开始,2表示取用的个数
String str = new String(a, 1, 2); // 打印bc
  • indexOf() / lastIndexOf
public class Demo { 
  // 查找指定字符串是否存在 
  public static void main(String[] args) { 
    String str1 = "abcdefmnabc"; 
    // 从头开始查找是否存在指定的字符 
    System.out.println(str1.indexOf("c")); // 打印2,这里传入99也是一样的,ASCII码对应
    // 从第4个字符位置开始往后继续查找 
    System.out.println(str1.indexOf("c", 3)); // 打印10,即最后一个
    System.out.println(str1.indexOf("abc")); // 传字符串也行,打印0 
    //若指定字符串中没有该字符则系统返回-1 
    System.out.println(str1.indexOf("z")); 
  } 

lastIndexOf()反向

charAt(int index)

// 返回指定下标的字符
String str1 = "abcdefmnabc"; 
// 若想打印字符串中每个字符,可以这样写
for (int i = 0; i < str.length(); i++) {
  System.out.println(str.charAt(i));
}

subString(int begin, int end)

// 返回该字符串的一个子字符串,区间是左闭右开的
String str1 = "abcdefmnabc";
str.subString(1, 4); // 返回bcd

toCharArray()

// 返回字符数组char[]
char[] chs = str.toCharArray();

String.valueOf()

// 可传入数字
System.out.println(String.valueOf(97)); // 仅仅是将97转换成字符串97,没有转换成'a'
// 传入字符数组,连接起来
 char[] chs = {'a','b', 98};
System.out.println(String.valueOf(chs)); // 打印abb

replace(char old, char new)

// 将指定的字符,全部替换成新的字符
String str1 = "abacd";
str.replace('a', 'e'); // 返回ebecd

可以传正则表达式(regex)的String类方法

  • split(String regex)
String str = "a1b2c3d";
String[] words = str.split("\\d"); // 按数字分割,注意返回的是String[]
for (String ch: words) {
  System.out.println(ch); // 依次打印abcd
}
  • replaceAll(String regex, String another)
String str = "a1b2c3d";
String new_str = str.replaceAll("\\d", "-"); // 把所有数字替换为"-"
System.out.println(new_str); // 打印a-b-c-d
  • matches()
// 判断该字符串是否和指定的正则表达式规则匹配
String str = "abc123de45@163.com";
// 匹配邮箱
boolean b = str.matches("\\w+@\\w+\\.[a-z]{2,3}");
System.out.println(b);

正则表达式的一般调用顺序

  • [abc]a或者b或者c
  • {2,}、{2,5}、{11}分别表示重复至少2次,重复2次到5次之间(包括),恰好重复11次
  • \w表示匹配单词字符[a-zA-Z_0-9]
  • \d匹配数字
  • \s匹配空白字符,包括空格、换行符、制表符
  • .表示匹配任意
  • +匹配一个或多个,*匹配0个或多个,?匹配0个或者1个
  • .*?非贪婪模式匹配任意字符串
Pattern p = Pattern.compile("1\\d{10}");
Matcher m = p.matcher("12345678901dhf18133338888");

// m.matches(); 返回false,虽然前面11位是满足的,但是Java中是matches()匹配整个,当整个字符串都和规则匹配才返回true
// Python中是从头开始匹配,若有满足,返回第一个匹配的,所有会匹配上12345678901

// find()找到所有和规则匹配的字符串。调用一次只能找到一个,若找到,指向下一个,用while找到所有
while (m.find())
  System.out.println(m.group()); // 会找到两个结果

// 注意不要使用了m.matches()后又去用m.find(),会有影响,我也不知道是为什么
Pattern p = Pattern.compile("1\\d{10}");
Matcher m = p.matcher("12345678901dhf18133338888");
boolean b = m.matches(); // 返回false,匹配后再用如下的find()
while (m.find())
  System.out.println(m.group()); // 只能找到最后一个结果18133338888

String一些简单的方法

  • trim()去除字符串两端的空格。

  • concat()连接两个字符串,功能和+连接字符串类似。

  • contains()返回boolean值,判断该字符串是否包含传入的字符串。

  • startWith()/endWith()判断该字符串是否以指定的字符串开头或者结尾。

  • toUpperCase()/toLowerCase()转换大小写,对每个字符进行操作。

  • getBytes(),使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

StringBuffer/StringBuilder

两个都是可变字符序列。StringBuffer可用于多线程,保证同步,线程安全。效率不高。StringBuilder一般用于单线程,不保证同步,线程不安全,但是效率高。一般用StringBuilder就行。

  • 长度可变
  • 可以存储不同类型的数据
  • 需要转换为字符串后来使用
public static void main(String[] args) throws InterruptedException {
        StringBuilder sb = new StringBuilder();
        sb.append(123);
        sb.append("abc"); // 可以添加任意类型数据
        System.out.println(sb); // 123abc
        sb.insert(3,"good");    // 第三个字符后面插入
        System.out.println(sb); // 123goodabc
        sb.replace(0, 3, "zzz"); // [0,3)区间的替换
        System.out.println(sb); // zzzgoodabc
        System.out.println(sb.length()); // 10
        sb.setLength(20);
        sb.setCharAt(19,'z');
        System.out.println(sb); // zzzgoodabc         z,中间有9个空格
        sb.deleteCharAt(19);
        System.out.println(sb); // zzzgoodabc         ,后面有10个空格
        System.out.println(sb.reverse()); // 字符序列反转,         cbadoogzzz,前面10个空格
        System.out.println(sb.capacity()); // 34,容量是通常大于长度的
        //sb.setLength(0); 删除该字符序列的一种方法,长度设置为0
        sb.delete(0, sb.length()); // 删除该字符序列的另外一种方法,删除整个区间内的字符
    }

by @sunhaiyu

2016.12.14

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • 一、String 类 1、定义: 1、从概念上讲,java字符串就是Unicode字符序列。每个用双引号括起来的字...
    玉圣阅读 1,505评论 0 1
  • Tip:笔者马上毕业了,准备开始 Java 的进阶学习计划。于是打算先从 String 类的源码分析入手,作为后面...
    石先阅读 11,937评论 16 58
  • 1 String是不可变类 这句话其实大家都很熟悉了,那么具体什么是不可变类呢?一般认为:当对象一旦创建完成后,在...
    adXiang阅读 409评论 0 0
  • 继上篇我们谈论了Celery的基本知识后,本篇继续讲解如何一步步使用Celery构建分布式爬虫。这次我们抓取的对象...
    resolvewang阅读 4,606评论 1 24