String类总结/StringBuffer/StringBuilder

本文目录


在复习String的方法之前,你先得准备一点基础知识。下面这篇博文是很好的。
String类不可变以及不可变类总结


准备刷字符串的算法题,但先得花点时间复习总结一下String类的相关方法,磨刀不误砍柴工。
这里也附上ASCII表,供查阅用。
在这里插入图片描述

方法

1.char charAt(int index)

        String str = "LeetCode";
        //1.读取字符
        char ch1 = str.charAt(0);//L
        System.out.println(ch1);
        //2.遍历
        for (int i = 0; i < str.length(); i++){
            System.out.print(str.charAt(i));//LeetCode
        }
        //3.计算字符出现次数
        int counter = 0;
        for (int i = 0; i < str.length(); i++){
            if (str.charAt(i) == 'e'){
                counter++;
            }
        }
        System.out.println("其中e出现了" + counter + "次");//3

2.boolean equals(Object obj)

如果字符串长度和里面的字符都相等,那就返回true

3.boolean equalsIgonoreCase(String string)

4.int compareTo(String string)

        String str1 = "LeetCode";
        String str2 = "Leetcode";
        String str3 = "LeetCodeGood5";
        //1.从首字母开始遍历比较,找到不同的ASCII码就返回它们的差值
        System.out.println(str1.compareTo(str2));//-32
        //2.当有一个字符串便利完成时,返回长度的差值
        System.out.println(str1.compareTo(str3));//-5
        System.out.println(str1.compareTo("Leet"));//4
        System.out.println(str1.compareTo("LeetCode"));//0

        //3.如果不用length()方法怎么求长度
        System.out.println(str1.compareTo(""));//8
        System.out.println("".compareTo(str1));//-8
        //注意:compareTo() method is case sensitive区分大小写.
        //可用compareToIgnoreCase() Method
        System.out.println(str1.compareToIgnoreCase(str2));//0

下面是compareTo方法的底层代码
在这里插入图片描述

5.int compareToIgnoreCase(String string)

6.boolean startsWith(String prefix,int offset)

        String str1 = "Leet Code";
        //1.找到前缀prefix则返回true,区分大小写
        System.out.println(str1.startsWith("Lee"));//true
        System.out.println(str1.startsWith("lee"));//false
        System.out.println(str1.startsWith("eet"));//false
        //2.从toffset开始找
        System.out.println(str1.startsWith("Co",5));//true

        //3.请找出字符串数组中具有相同前缀"L"的字符串个数
        int count = 0;
        String[] strings = new String[]{"Leet","code","Lucky!"};
        for (int i = 0; i < strings.length; i++){
            if (strings[i].startsWith("L")){
                count++;
            }
        }
        System.out.println(count);//2

7.boolean startsWith(String prefix)

8.boolean endsWith(String suffix)

        String str1 = new String("LeetCode");
        //1.后缀suffix,区分大小写
        System.out.println(str1.endsWith("ode"));//true

找了一道ACM算法题,改编了一下练练手。

	字符串的前缀和后缀
    Description

    字符串的前缀是指字符串的任意首部。
    比如字符串“abbc”的前缀有“a”,“ab”,“abb”,“abbc”。
    同样,字符串的任意尾部是字符串的后缀,
    “abbc”的后缀有“c”,“bc”,“bbc”,“abbc”。
    现在给出一些字符串, 找出每个字符串中含字符种类最多的前缀或后缀。

    Input

    输入第一行是一个整数n(1<=n<=50),表示有n个字符串。
    下面有n行,每行的格式是这样:字符串str 字符ch
    字符串str由小写字母组成,长度不超过100000,字符ch只有两个取值’P’,’S’。
    如果ch为’P’,则找出含字符种类最多的前缀。
    如果ch为’S’,则找出含字符种类最多的后缀。

    Output

    对于每个字符串,输出一行。
    输出格式是这样:String #X: Y
    按字符串的读入顺序,X从1开始递增到n。
    Y是满足条件的前缀字符串或后缀字符串,
    如果有多个前缀或后缀满足条件,则取长度最小的一个。

我改简单点,练练手,操作一个字符串并求出它的前后缀就好。

    public String[] FindPreAndSuf(String str){
        if (str == null || str == ""){
            return null;
        }
        String[] strs = new String[2];
        int left = 0;
        int right = str.length() - 1;
        while (left != right){
            if (str.charAt(left) == str.charAt(right)){
                left = 0;
                right--;
            }else {
                left++;
            }
        }
        strs[0] = str.substring(0,left + 1);
        left = 0;
        right = str.length() - 1;
        while (left != right){
            if (str.charAt(left) == str.charAt(right)){
                right = str.length() - 1;
                left ++;
            }else {
                right--;
            }
        }
        strs[1] = str.substring(right,str.length());
        return strs;
    }

9.int hashCode()

顺便测试了一下isEmpty方法

        String str = "";
        String str1 = " LEET CODE  ";
        System.out.println(str.isEmpty());//true
        System.out.println(str1.trim());//LEET CODE

        //s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
        System.out.println(str.hashCode());//0
        System.out.println(str1.hashCode());//567224773

10.int indexOf(int ch)

从fromIndex参数开始向右搜索,
但lastIndexOf里的是从fromIndex参数向坐搜索。

       String str1 = "LeetCode";
        System.out.println(str1.indexOf("ee",2));//-1
        System.out.println(str1.lastIndexOf('e',13));//7

11.int indexOf(int ch,int fromIndex)

12.int lastIndexOf(int ch)

13.int lastIndexOf(int ch,int fromIndex)

14.int indexOf(String str)

15.int lastIndexOf(String str)

16.String substring(int beginIndex)

子串操作很重要,我上面发的那道算法题也用到了这个方法,值得注意的是java的很多方法参数都是左闭右开区间

17.String substring(int beginIndex,int endIndex)

18.String concat(String str)

将字符串加在原字符串的尾部

        String str = "LeetCode";
        str = "www.".concat(str).concat(".com");
        System.out.println(str);//www.LeetCode.com

输出:
在这里插入图片描述
注意:MySQL也有串联字符串函数CONCAT()作为串联运算符,串联中的各个元素是在括号中用逗号分隔开来的。

SELECT CONCAT(Buyer, ' in ', Department) AS Sponsor
FROM SKU_DATA;

优化写法:

SELECT DISTINCT RTRIM(Buyer) + ' in ' + Rtrim(Department) AS Sponsor
FROM SKU_DATA;

这个查询的结果在视觉上更好一些。

19.String replace(char oldChar, char newChar)

代替方法有三个:

	replace(), replaceFirst(),replaceAll()
  • replace()就是用newChar代替oldChar,参数可以都用字符也可以都用字符串,但不能混搭。不能识别REGEX,所以也不能代替数字标点符号等。
  • replaceFirst()只会代替第一个子串,后面的不变,支持regex
  • replaceAll()是全都代替,支持regex

20.boolean contains(CharSequence s)

这里介绍一下CharSequences,是一个接口
在这里插入图片描述

  • contains方法通常用在if-else结构里。
  • 有大小写区别,所以通常会和toUpperCase等一起用。

21.String toUpperCase(Locale locale)

22.String toUppercase()

23.public String intern()

在我之前的某篇文章也讨论过这个。这个方法先回搜索常量池里有没有提及的字符串对象,如果有就返回对象的引用,没有的话就在常量池创建一个内存空间来放字符串对象,然后返回对象的引用。
下面的例子是常量池已经有了那个字符串对象,所以直接返回引用。

	String str1 = "beginnersbook";  //这个其实等同于”beginnersbook“.intern();自动创建了对象在常量池。
	String str2 = new String("beginnersbook").intern(); 
	System.out.println("str1==str2: "+(str1==str2));//true

What is the purpose of Java’s String.intern()?

24.public boolean isEmpty()

上面讨论过这个,如果字符串是"“的话就是空,是” "不算空,是null的话会报错,字符串未初始化也报错,理解就行。

25.public static String join()

public static String join(CharSequence delimiter,
                      CharSequence... elements)

静态方法,而且要区别于concat,这个是通过delimiter(即分隔符)把后面所有的元素依次连接起来。

String message = String.join("-", "This", "is", "a", "String");
// message returned is: "This-is-a-String"
注意如果一个元素是null,”null"会被连接进来。
        System.out.println(String.join("%","crazy",null,"!"));
       //crazy%null%!

通常用来做列表元素的连接。

        List<String> list = Arrays.asList("LeetCode","CSDN","bilibili");
       //System.out.println(list.add("failed"));//UnsupportedOperationException
        System.out.println(String.join("|",list));

Output:

LeetCode|CSDN|bilibili

26.String replaceFirst(String regex,String replacement)

27.String replaceAll(String regex,String replacement)

28.String[] split(String regex,int limit)

这个是难点,先好好把regex掌握熟练。
Java Regular Expressions (java regex) Tutorial with examples

29.String[] split(String regex)

30.String toLowerCase(Locale locale)

31.public static String format()

静态方法

public static String format(String format,
            Object... args)

返回一个使用了特定format的字符串。
%c – Character
%d – Integer
%s – String
%o – Octal
%x – Hexadecimal
%f – Floating number
%h – hash code of a value
感觉不怎么重要,可以跳过。

32.String toLowerCase()

33.String trim()

去空格,只能去除字符串两边的空格。
比如" LEET CODE "
.trim()后中间的空格还在"LEET CODE"


可是像我们这么有好奇心的人,怎么会停留在只会消除左右空格呢?其实是因为我刷题遇到了才回来补的hhh

  1. 中间空格怎么消:replace(" ",""),这个就消去全部空格,包括中间的。
  2. 不想消前面:("A" + str).trim().substring(1);
  3. 中间很多空格,但我想保留一个:
        String str1 =  "  Leet   Code  ";
        System.out.println(str1.trim());
        System.out.println(str1.replace(" ",""));
        System.out.println(("A" + str1).trim().substring(1));
        System.out.println(str1.replaceAll("\\s+"," ").trim());

在这里插入图片描述
一开始我还想说出题人怎么要求这么怪啊,还特意保留中间一个空格,看来是有学问的嘛,考了不少知识。

34.char[] toCharArray()

返回字符数组,长度和字符串长度相等,这个时候就可以用for-each遍历了。

35.static String copyValueOf(char[] data)

其实就是把数组整进来弄成字符串返回。

36.static String copyValueOf(char[] data,int offset,int count)

37.void getChars(int srcBegin,int srcEnd,char[] dest,int destBegin)

38.static String valueOf()

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

补充一个就是参数也可以是char[]。

39.boolean contenEquals(StringBuffer sb)

        String str1 = "First String";
        String str2 = "Second String";
        StringBuffer str3 = new StringBuffer( "Second String");
        StringBuffer str4 = new StringBuffer( "First String");
        System.out.println(str1.equals(str4));//false
        System.out.println("str1 equals to str3:"+str1.contentEquals(str3));
        System.out.println("str2 equals to str3:"+str2.contentEquals(str3));
        System.out.println("str1 equals to str4:"+str1.contentEquals(str4));
        System.out.println("str2 equals to str4:"+str2.contentEquals(str4));

用来比较String和String Buffer的内容,为什么不能用equals呢?
看源码,if (anObject instanceof String),不满足这个就直接return false了。
在这里插入图片描述

40.boolean regionMatches(int srcoffset, String dest, int destoffset, int len)

可以用来比较输入的子串和特定的字符串的子串

       String str1 = new String("Hello, How are you");
       String str2 = new String("How");
       String str3 = new String("HOW");

       System.out.print("Result of Test1: " );
       System.out.println(str1.regionMatches(7, str2, 0, 3));

       System.out.print("Result of Test2: " );
       System.out.println(str1.regionMatches(7, str3, 0, 3));

       System.out.print("Result of Test3: " );
       System.out.println(str1.regionMatches(true, 7, str3, 0, 3));

Output:

Result of Test1: true
Result of Test2: false
Result of Test3: true

41.boolean regionMatches(boolean ignoreCase, int srcoffset, String dest, int destoffset, int len)

42.byte[] getBytes(String charsetName)

43.byte[] getBytes()

44.int length()

这是方法,记得带()就行,区别于数组的length属性

45.boolean matches(String regex)

       String str = new String("Java String Methods");

       System.out.print("Regex: (.*)String(.*) matches string? " );
       System.out.println(str.matches("(.*)String(.*)"));

       System.out.print("Regex: (.*)Strings(.*) matches string? " );
       System.out.println(str.matches("(.*)Strings(.*)"));

       System.out.print("Regex: (.*)Methods matches string? " );
       System.out.println(str.matches("(.*)Methods"));

Output:

Regex: (.*)String(.*) matches string? true
Regex: (.*)Strings(.*) matches string? false
Regex: (.*)Methods matches string? true

46.int codePointAt(int index)

String类异常分析

做题时候遇到一个异常:

java.lang.StringIndexOutOfBoundsException: String index out of range: 5
        String str0 = "ab";
        System.out.println(str0.charAt(5));

charAt(i),要求-1 < i < str0.length(),在String数组里面遍历字符容易出这个问题。


StringBuffer

What java documentation says about StringBuffer:
From StringBuffer javadoc:
A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.

1.常用方法

  1. append在这里插入图片描述
        StringBuffer sb= new StringBuffer("Hello,");
        sb.append("How ");
        sb.append("are");
        sb.append("\n");
        sb.append("you??\t");
        sb.append("lisz");
        System.out.println(sb);

Output:

Hello,How are
you??	lisz
  1. substring
    在这里插入图片描述

[start,end)

  1. replace
    在这里插入图片描述

[start,end)

  1. reverse

在这里插入图片描述

StringBuffer sb= new StringBuffer("LeetCode ");
        sb.append("Hello World!");
        sb.reverse();
        System.out.println(sb);

Output:

!dlroW olleH edoCteeL
  1. insert
    在这里插入图片描述
  2. delete
    在这里插入图片描述

[strat,end)

2.null的问题

上面String类的join方法已经遇到了类似的问题。
join()方法
当我们append null到StringBuffer对象,其实等价于

append("null")

大部分情况下,我们都是不想要这种结果的,所以可以使用

if (str != null) sb.append(str);

3.StringBuilder vs StringBuffer

  1. 同步性:StringBuffer方法都是用synchronized修饰的而StringBuilder方法是non-synchronized的。意味着为了线程安全你必须选择StringBuffer。
  2. 效率:在一个同步环境里,一个单线程可以专注一个活动而不是把工作分配到多个线程里,这让StringBuffer效率更低(it is synchronized),而StringBuilder效率更高(it is not synchronized)
  3. 相似性:都是可变的,可以用自带的各种方法对其内容进行变更
  4. 选哪个?:他们的操作、方法等都几乎相同,这意味着StringBuffer能做的StringBuilder一般也能做。最重要的是要考虑线程安全:如果你认为操作应该要线程安全的就使用StringBuffer,在其它情况,StringBuilder会是更好的选择(功能相同而且效率更高)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值