Detailed String class in Java

 

table of Contents

String class is created:

A typical distribution of memory on the String class 

.intern () use 

Immutability of strings

Characters, character strings, and byte conversion

Common string operation

 StringBuffer和StringBuilder

String typical example


String class is created:

String is caused by a string of characters enclosed in double quotes. There are three main ways to create:

 String str = "abcdef";  //1、直接赋值
 String str2 = new String("abcdef");  //2、new一个String对象
 char[] array = {'a', 'b', 'c', 'd', 'e', 'f'};  //3、通过字符数组
 String str3 = new String(array);

Memory distribution:

First, the direct assignment of the way: character constants are stored in the constant pool, and only this one.

The second method: String underlying implementation has a value [] array,

 Abcdef get constant pool of existing String object is constructed, there is a String object value [] array to store the address of abcdef. It produced two objects.

The third method:

String constructor underlying follows:

A typical distribution of memory on the String class 

ps: == basic types with respect to the comparison value is equal, with respect to the reference type is to compare address are equal.

        String str1 = "abcdef";
        String str2 = new String("abcdef");
        System.out.println(str1 == str2); //1、false 上图可表明

        String str3 = "abc" + "def";
        System.out.println(str1 == str3); //2、true "abc" 和 "def"
        都是字符常量,在编译时已经合并为abcdef,常量池中相同的字符串只能存在一份,因此str1和str3指 
        向同一块空间

        String str4 = "abc" + new String("def");
        System.out.println(str1 == str4); //3、false

        String str5 = "abc";
        String str6 = "def";
        String str7 = str5+str6;
        System.out.println(str1 == str7); //false 和第三个思想类似

        String str8 = str5 + new String("def");
        System.out.println(str1 == str8); //false 和第三个思想类似

The third is as puzzling as it is in fact distributed in memory:

 

.intern () use 

 String str1 = "abcdef";
 String str2 = new String("abcdef").intern();
 System.out.println(str1 == str2);

Gee, the above code is run out turned out to be true. . intern (); method is very powerful. The role of the manual into the pool.

1, intern () method is a native method, the bottom is implemented by C / C ++ is.

 2, if the string to be present in the constant pool into the pool which, among constant pool directly returns the address of the string constant
      if the constant pool does not exist, then the string in constant pool into the pool them.

Immutability of strings

Piece of code:

 String str = "hello";
 str = str + "world";
 str += "!!";
 System.out.println(str);

This code must be printed out helloworld !!, but not modify the value of the original in str, but creates a new object, reflecting the immutability of the string. And every splice will have a new object.

So why else String variable: 
1. facilitate the achievement of a string object pooling if the String variable, then the object pool needs to consider the question of when a deep copy of the string.
2. immutable objects are thread-safe
3. immutable objects more convenient cache hash code, a key can be more efficiently stored in the hash Map 

如何有一个字符串"Hello",一定要把它改为"hello",那么就要用到反射了,反射需要先得到Class对象,存放在方法去,存放的是类的信息。具体方法如下:

  public static void main(String[] args) throws NoSuchFieldException , 
  IllegalAccessException{
        String str = "Hello"; //new String()
        Class cls = String.class; //获取class对象
        Field field = cls.getDeclaredField("value"); //把str中的value获取到
        field.setAccessible(true);
        char[] value = (char[])field.get(str);
        value[0] = 'h';
        System.out.println(str);
    }

字符、字节和字符串的转换

字符串和字符之间的转化:

1.字符转化为字符串

 char[] array = {'a', 'b', 'c', 'd', 'e', 'f'};  
 String str3 = new String(array);

2.字符串转化为字符

String str = "abcdef";
char[] array = str.toCharArray();

 

字符串和字节的转化:

1.字节转化为字符串

byte[] bytes = {97, 98, 99, 100};
String str = new String(bytes);
System.out.println(str); //abcd

2.字符串转化为字节

 String str1 = "白";
 byte[] bytes1 = str1.getBytes("Unicode");
 System.out.println(Arrays.toString(bytes1)); //获取字符串的编码方式

byte[] and char[] 的适用范围:
byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合 针对二进制数据来操作
char[] 是吧
String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候

字符串的常用操作

1、字符串比较:

        String str = "Hello";
        String str1 = "hello";
        System.out.println(str.equals(str1));  //false
        System.out.println(str.equalsIgnoreCase(str1)); //true
        System.out.println(str.compareTo(str1)); //-32

字符串比较有三种方法,equals是比较字符串的值是否相等区分大小写,.equalsIgnoreCase不区分大小写。而compareTo()返回一个整型。

2、字符串查找

        String str = "abcdefg";
        //是否包含 底层调用indexOf()函数
        System.out.println(str.contains("def")); //true

        //查找子串-》返回下标
        System.out.println(str.indexOf("bcd")); //1

        //从后往前查找子串-》返回下标
        System.out.println(str.lastIndexOf("cd")); //2

        //判断是否以指定字符串开头
        System.out.println(str.startsWith("ab")); //true

        //判断是否以指定字符串结束
        System.out.println(str.endsWith("ef")); //false

3、 字符串替换

        String str = "abcabcba";
        System.out.println(str.replace('a','A')); //AbcAbcbA
        System.out.println(str.replace("ab","##")); //##c##cba
        System.out.println(str.replaceAll("ab","##")); //##c##cba
        System.out.println(str.replaceFirst("abc","**")); //**abcba

4、字符串拆分

        String str = "a,bc ab,c b,a";
        //[a,bc, ab,c, b,a]
        String[] string = str.split(" "); //以空格为间隔符进行拆分
        for (int i = 0; i < string.length; i++) {
            String[] string2 = string[i].split(",");
            // [a, bc]
            //[ab, c]
            //[b, a]
            System.out.println(Arrays.toString(string2));
       }
  String str = "a,bc ab,c b,a";
        //[a,bc, ab,c,b,a]
  String[] string = str.split(" ",2); //所要分得的组数最大是2

 注意有些特殊字符作为分隔符可能无法正确拆分,需要加上转义。

        String str = "193.168.1.1";
        String[] strings = str.split("\\.");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }

注意:第一个\表示把 "\\" -> "\",第二个"\"是正则表达式"\." -> "." 
 字符"|","*","+"也是这样的规则,并且当一个字符串中有多个分隔符时,可以用"|"作为连字符。

5、字符串截取

        String str = "abcdefg";
        System.out.println(str.substring(2)); //cdefg
        System.out.println(str.substring(2,5)); //左闭右开   cde

6、其他操作 

1)去掉字符串左右的空格,保留中间空格

        String str = "   abc d e     ";
        System.out.println(str.trim()); //abc d e

2)大小写转换

        String str = "abCDEFg";
        System.out.println(str.toUpperCase()); //ABCDEFG
        System.out.println(str.toLowerCase()); //abcdefg

3)字符串入池操作

        char[] array = {'a', 'b', 'c'};
        String str = new String(array);
        str.intern();

 4)字符串连接,等同于“+”,不入池

        String str = "hello";
        System.out.println(str.concat("Java")); //helloJava

 5)判断字符串是否为空,取得字符串长度

        String str = "";
        System.out.println(str.isEmpty()); //true
        System.out.println(str.length()); // 0 注意是方法

 StringBuffer和StringBuilder

任何字符串常量就是String对象,而且String的常量一旦声明不可改变,如果改变对象内容,改变的只是引用的指向。由于字符串的不可变性,为了方便字符串的修改,提供StringBuffer和StringBuilder类,这两个大部分功能是相同的。

String的拼接底层会优化为StringBuilder

   public static void main(String[] args) {
        String str = "abc";
        String str2 = str + "def";
        System.out.println(str2);
    }

StringBuilder的拼接并没有产生新的对象,是在原来对象进行修改。append();方法实现

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abc");
        System.out.println(sb); //abc
        sb.append("java"); 
        System.out.println(sb); // abcjava
    }

ps:解释String、StringBuffer、StringBuilder的区别

1、String的内容不可修改,StringBuffer、StringBuilder的内容可以修改。
2、StringBuffer、StringBuilder使用方法是一样的,但是StringBuffer线程安全,String和StringBuilder线程不安全
3、String之间的拼接底层优化为了StringBuilder(append();方法)。StringBuffer、StringBuilder的append()不会产生新的对象(return this)

注意:String和StringBuffer不能直接转化,如果想要互相转化,可以:
String变为StringBuffer:利用StringBuffer的构造方法或append()方法
StringBuffer变为String:调用toString方法

 

 

字符串典型例题

1、输入两个字符串,需要无冗余拼接

   
   public static String myAppend(String str) {
        //分割
         String[] strs = str.split(" ");
        //String ret = "";
        //for(String s : strs) {
        //    ret += s;
        //}
        //return ret;

        StringBuilder sb = new StringBuilder();
        for(String s : sb) {
           sb.append(s);
        }
        return sb.toString();
       
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        System.out.println(myAppend(str));
    }

2、将字符串进行逆置

    //逆置字符串
    public static String reverse(String string) {
        char[] array = string.toCharArray();
        int left = 0;
        int right = array.length-1;
        while (left < right) {
            char tmp = array[left];
            array[left] = array[right];
            array[right] = tmp;
            left++;
            right--;
        }
        return String.copyValueOf(array);
    }

    public static void main(String[] args) {
        String str = "abcdef";
        String ret = reverse(str);
        System.out.println(ret);
    }

3、给定一个字符型的数组chas和一个整数size,请把大小为size的左半区整体右移到右半区,右半区整体移动到左边。

逆置前半部分-》逆置后半部分-》全部逆置

    public static String reverse2(String str, int start, int end) {
        char[] array = str.toCharArray();
        while (start < end) {
            char tmp = array[start];
            array[start] = array[end];
            array[end] = tmp;
            start++;
            end--;
        }
        return String.copyValueOf(array);
    }

    public static String fun(String str, int k) {
        str = reverse2(str, 0, k-1);
        str = reverse2(str, k,str.length()-1);
        str = reverse2(str,0,str.length()-1);
        return str;
    }

    public static void main(String[] args) {
        String str = "abcdef";
        System.out.println(fun(str,3)); //defabc
    }

4、字符串的转化(压缩) aabbccda -》 2a2b2c1d1a

    //字符串的转化(压缩) aabbccda -》 2a2b2c1d1a
    public static String changeString(String str) {
        char ch = str.charAt(0);
        StringBuilder stringBuilder = new StringBuilder();
        int count = 1;
        for (int i = 1; i < str.length(); i++) {
            if (ch == str.charAt(i)) {
                count++;
            } else {
               stringBuilder.append(count).append(ch);
               ch = str.charAt(i);
               count = 1;
            }
        }
        return stringBuilder.append(count).append(ch).toString(); //拷贝最后一组
    }

    public static void main17(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        System.out.println(changeString(str));
    }

5、i am student -> stduent am i

    //i am student -> stduent am i
    //先整体逆置,再单词逆置
    public static String reverseString(char[] array, int start, int end) {
        while (start < end) {
            char tmp = array[start];
            array[start] = array[end];
            array[end] = tmp;
            start++;
            end--;
        }
        return String.copyValueOf(array);
    }

    public static String fun(String str) {
        char[] array = str.toCharArray();
        //整体逆置
        reverseString(array,0,str.length()-1);
        //逆置单词
        int i = 0;
        int j = 0;
        while (i < array.length) {
            if (array[i] == ' ') {
                i++;
                j++;
            } else if (j == array.length || array[j] == ' ') {
                reverseString(array,i,j-1);
                i = ++j;
            } else {
                j++;
            }
        }
        return String.copyValueOf(array);
    }

    public static void main(String[] args) {
        String str = "i am stdent";
        System.out.println(fun(str));
    }

 

 

发布了51 篇原创文章 · 获赞 14 · 访问量 2315

Guess you like

Origin blog.csdn.net/qq_41185460/article/details/103267357
Recommended