Consolidate the basis of Java Series 3: get to know a text String common interview questions, from basic to actual combat, more principle analysis and parsing source code!

table of Contents

This series of articles will arrange to me on GitHub's "Java Interview Guide" warehouse, more exciting content please go to my warehouse View

https://github.com/h2pl/Java-Tutorial

Like it under the trouble spots Star Kazakhstan

Article first appeared in my personal blog:

www.how2playlife.com

This article is a micro-channel public number [of] Java technology quack "reinforce the Java Foundation series Bowen," in which a Part of this article from the network, to the subject of this article speaks clear and thorough, and I think a lot of good integration of technology blog content, which cited a number of good blog posts, if infringement, please contact the author. This blog series will show you how to from entry to advanced, step by step to learn the basics of Java, and started actual combat, then understand Java knowledge to realize the principles behind each point, a more complete understanding of the entire Java technology system, to form their own intellectual framework. In order to summarize and test your learning outcomes, this series will provide every knowledge point corresponding interview questions and suggested answers.

If you have any suggestions for this series of articles, or have any questions, you can also concerned about the number of public rivers and lakes [] Java technology to contact the author, you are welcome to participate in the creation and revision of this blog series.

[TOC]

string basis

Java String class

String widely used in the Java programming in Java strings belong to the object, Java provides the String class to create and manipulate strings.

Creating strings

The easiest way to create a string as follows:

String greeting = "rookie course";

Encountered string constants in the code, the value here is " rookie tutorial " ", the compiler creates a String object with the value.

And other objects, you can use keywords and constructors to create String objects.

String class has 11 kinds of construction methods that provide different parameters to initialize a string, such as a character array parameters:

StringDemo.java file code:

public class StringDemo{    public static void main(String args[]){       char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'};       String helloString = new String(helloArray);         System.out.println( helloString );    } }复制代码

The above examples compiled results are as follows:

runoob复制代码

Note: String class is immutable, so once you create a String object, then its value can not be changed (see detailed notes partial parsing).

If you need to do a lot of modifications to the string, you should choose to use StringBuffer & StringBuilder class .

String basic usage

Common way to create a String object

(1) String s1 = "mpptest"

(2) String s2 = new String();

(3) String s3 = new String("mpptest")

String commonly used method, as shown in FIG usage, particularly asked of Mother

Using three methods: lenth () substring () charAt ()

package com.mpp.string; public class StringDemo1 {public static void main (String [] args) {// definition of a character string "Night to Day For snow can not drink" String str = "night to day to be able to drink snow no cup "; System.out.println (" length of the string are: "+ str.length ()); snow word printout charAt // string (int index) System.out.println (str.charAt ( 4)); // day to be taken substring System.out.println (str.substring (2)); // index2 taken from the start until the last substring, comprising 2System.out.println (str.substring (2, 4)); // index taken from the sub-string 2 to 4, comprising 2 does not include the tail care regardless 4}}

Using two methods, find a character or substring first / last occurrence position in the string: indexOf () lastIndexOf ()

package com.mpp.string; public class StringDemo2 {public static void main (String [] args) {String str = new String ( "Zhao customer unadorned Hu Ying Hu Ying Wu hook frost out"); // Find Hu in a string the position of the first occurrence of System.out.println ( "" Hu "position at the first occurrence of the string:" + str.indexOf ( "Hu")); // Find the substring "Hu Ying" in character System.out.println position of the first occurrence of the string ( "" Ying Hu "position at the first occurrence of the string" + str.indexOf ( "Hu Ying")); // Find Hu in a string the last time to appear System.out.println (str.lastIndexOf ( "Hu")); // Find the substring "Hu Ying" position System.out.println the last in a string that appears (str.lastIndexOf ( "Hu Ying")); // from indexof to position 5, to find the first occurrence of "Miss" System.out.println (str.indexOf ( "Wu", 5));}}

Conversion between a string and a byte array

package com.mpp.string; import java.io.UnsupportedEncodingException; public class StringDemo3 {public static void main (String [] args) throws UnsupportedEncodingException {// String str mutual conversion between the strings and the byte array = new String ( " saddle according hhhabc silver White Horse Sa Da, such as meteor "); // convert the string into a byte array, and print out the byte [] arrs = str.getBytes (" GBK "); for (int i = 0; i) {System .out.print (arrs [i]);} // convert the string into a byte array System.out.println (); string str1 = new string (arrs, "GBK"); // consistent character set, otherwise, garbled System.out.println (str1);}}

== distinction between the operator and equals:

Citations and references pointing to the address pointed to

package com.mpp.string; public class StringDemo5 { public static void main(String[] args) {String str1 = "mpp";String str2 = "mpp";String str3 = new String("mpp");

    System.out.println(str1.equals(str2)); //true  内容相同
    System.out.println(str1.equals(str3));   //true  内容相同
    System.out.println(str1==str2);   //true   地址相同
    System.out.println(str1==str3);   //false  地址不同复制代码

}}

Immutability of strings

Once a String object is created, it can not be modified, it is immutable

In fact, the so-called modification is to create a new object, points to the same memory space

The figure above, s1 no longer point to the memory space where imooc, but point to a hello, imooc

String connection

@Test
public void contact () {
    //1连接方式
    String s1 = "a";
    String s2 = "a";
    String s3 = "a" + s2;
    String s4 = "a" + "a";
    String s5 = s1 + s2;
    //表达式只有常量时,编译期完成计算
    //表达式有变量时,运行期才计算,所以地址不一样
    System.out.println(s3 == s4); //f
    System.out.println(s3 == s5); //f
    System.out.println(s4 == "aa"); //t

}复制代码

Difference String, String builder and the String buffer

String is a Java-based and important class, and also the typical implementation Immutable String class is declared final class, in addition to hash this property other properties are declared as final, because of its immutability, so time will produce a string such as splice many useless intermediate object, or if you frequently carry out such operations have an impact on performance.

In order to solve a large class StringBuffer string concatenation create many problems to provide an intermediate objects, there is provided a method append and add, can be added to the end of a string or a specified position existing sequence, it is essentially a security thread may be modify the sequence of characters, all data modification methods are added synchronized. But to ensure the security thread is the need of the price performance of.

In many cases we do not need thread-safe string concatenation operation, this time StringBuilder debut, StringBuilder is JDK1.5 release, and it is essentially no different on StringBuffer, it is to remove that part of the guarantee thread safety, reduce overhead .

Both StringBuffer and StringBuilder inherit AbstractStringBuilder, the bottom layer is the use of modifiable char array (hereinafter JDK 9 is a byte array).

So if we have a lot of string concatenation, if you can predict the size would be best to set up capacity in the new StringBuffer or StringBuilder time to avoid the overhead of multiple expansion. Expansion to abandon the original array, but also for creating a new copy of an array of arrays.

We normally develop a small amount of string concatenation usually not really need to worry too much, for example,

String str = "aa"+"bb"+"cc";

This is not like a string variable, the compiler stage direct synthesis "aabbcc", and then see a string constant pool (constant pool will talk below), there is no, there is also a direct reference, not to generate constant pool, returns a reference.

If the band is variable, in fact, not much impact, JVM will help us optimize.

1 priority in the business scenario using String string does not change often occurs (code more clear and concise). As constant declaration, a small amount of string manipulation (splice, delete, etc.).

2, in the case of the single thread, if a large number of operating string, the string should be used to operate StringBuilder. You can not use String "+" but the use of stitching to avoid a large number of intermediate objects useless, space-consuming and inefficient executed (newly created object, the object takes much time recovery). As JSON packaging and the like.

3, in the case of multi-thread, string operations if a large number of cases, should be used StringBuffer. The HTTP parameter parsing and packaging.

String class source code analysis

String type of intern

public void intern () {
    //2:string的intern使用
    //s1是基本类型,比较值。s2是string实例,比较实例地址
    //字符串类型用equals方法比较时只会比较值
    String s1 = "a";
    String s2 = new String("a");
    //调用intern时,如果s2中的字符不在常量池,则加入常量池并返回常量的引用
    String s3 = s2.intern();
    System.out.println(s1 == s2);
    System.out.println(s1 == s3);
}复制代码

String type of equals

//字符串的equals方法
//    public boolean equals(Object anObject) {
//            if (this == anObject) {
//                return true;
//            }
//            if (anObject instanceof String) {
//                String anotherString = (String)anObject;
//                int n = value.length;
//                if (n == anotherString.value.length) {
//                    char v1[] = value;
//                    char v2[] = anotherString.value;
//                    int i = 0;
//                    while (n-- != 0) {
//                        if (v1[i] != v2[i])
//                            return false;
//                        i++;
//                    }
//                    return true;
//                }
//            }
//            return false;
//        }复制代码

StringBuffer和Stringbuilder

The bottom layer is a variable character array value inherits the parent class

/**

- The value is used for character storage.
  */
  char[] value;
  初始化容量为16

/**

- Constructs a string builder with no characters in it and an
- initial capacity of 16 characters.
  */
  public StringBuilder() {
  super(16);
  }
  这两个类的append方法都是来自父类AbstractStringBuilder的方法

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}
@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}复制代码

append method

Stringbuffer on most operations involving the addition of a string to modify the synchronized keyword to ensure thread safety, efficiency is low.

String type using the + operator e.g.

String a = "a"

a = a + a; when, in fact, a first package into stringbuilder, then append method call returns with tostring, when the character string adding heavy use, will generate a large amount of stringbuilder instance, it is very wasteful, this stringbuilder time should be used instead of string.

Expansion

Note the call to a function in the append method

ensureCapacityInternal (count + len); the process is calculated after the append space is adequate, insufficient expansion, if desired, be

public void ensureCapacity(int minimumCapacity) {
    if (minimumCapacity > 0)
        ensureCapacityInternal(minimumCapacity);
}
private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0) {
        value = Arrays.copyOf(value,
                newCapacity(minimumCapacity));
    }
}复制代码

If the new value is greater than the string length for expansion of the length of the array

Length after expansion is generally twice the original 2 +;

If the length after expansion exceeds the maximum array length of the support jvm MAX ARRAY SIZE.

Two cases are considered

If the new string longer than the maximum int, an exception is thrown, or used directly as the maximum length of the array length of the new array.

private int hugeCapacity(int minCapacity) {
    if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
        throw new OutOfMemoryError();
    }
    return (minCapacity > MAX_ARRAY_SIZE)
        ? minCapacity : MAX_ARRAY_SIZE;
}
复制代码

delete

These two types of deletions:

We are calling the delete method to delete the parent class

public AbstractStringBuilder delete(int start, int end) {
    if (start < 0)
        throw new StringIndexOutOfBoundsException(start);
    if (end > count)
        end = count;
    if (start > end)
        throw new StringIndexOutOfBoundsException();
    int len = end - start;
    if (len > 0) {
        System.arraycopy(value, start+len, value, start, count-end);
        count -= len;
    }
    return this;
}
复制代码

In fact, the remaining characters copied back to the character array value.

Here used system.arraycopy to copy arrays, speed is relatively fast

system.arraycopy method

Knowing almost turn:

In the mainstream high-performance JVM (HotSpot VM system, IBM J9 VM system, JRockit system, etc.), it can be considered System.arraycopy () when copying arrays are reliable and efficient - if not efficient enough cases found, please report performance bug, certainly will soon be improved.

java.lang.System.arraycopy () method is declared as a native method in Java code. So the most naïve implementation is achieved by JVM JNI calls in the native code.

String of immutability

About the immutability of String, here turn a good answer

What is immutable?

String immutable is simple, as shown, to an existing string "abcd" assigned to the second "abcedl", not modify the data in the original memory address, but re-point a new object, the new address.

String relations and the JVM

Here we understand under the Java stack, Java heap, the method area and the constant pool:

Java stack (thread private data area):

    每个Java虚拟机线程都有自己的Java虚拟机栈,Java虚拟机栈用来存放栈帧,每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
复制代码

Java heap (thread-shared data area):

   在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配。
复制代码

The method area (thread shared data area):

   方法区在虚拟机启动的时候被创建,它存储了每一个类的结构信息,例如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容、还包括在类、实例、接口初始化时用到的特殊方法。在JDK8之前永久代是方法区的一种实现,而JDK8元空间替代了永久代,永久代被移除,也可以理解为元空间是方法区的一种实现。
复制代码

Constant pool (thread-shared data area):

    常量池常被分为两大类:静态常量池和运行时常量池。

    静态常量池也就是Class文件中的常量池,存在于Class文件中。

    运行时常量池(Runtime Constant Pool)是方法区的一部分,存放一些运行时常量数据。
复制代码

The following is important to understand that the string constant pool:

    字符串常量池存在运行时常量池之中(在JDK7之前存在运行时常量池之中,在JDK7已经将其转移到堆中)。

    字符串常量池的存在使JVM提高了性能和减少了内存开销。

    使用字符串常量池,每当我们使用字面量(String s=”1”;)创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就将此字符串对象的地址赋值给引用s(引用s在Java栈中)。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,并将此字符串对象的地址赋值给引用s(引用s在Java栈中)。
复制代码

    使用字符串常量池,每当我们使用关键字new(String s=new String(”1”);)创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么不再在字符串常量池创建该字符串对象,而直接堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s,如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,然后在堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s。
复制代码

Why String immutable?

JDK open source, java.lang.String class hands first three lines, is written like this:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {   
  /** String本质是个char数组. 而且用final关键字修饰.*/     
private final char value[];  ...  ...
 } 
复制代码

First String class is modified by the final keyword, indicating String can not be inherited. Look at the following, the main member field value String class is a char [] array, but with a final modified.

After the final modified fields to create never changes. Some people think this story is over, it did not. Because although the value is immutable, it is only a reference value of this address is not changed. Array can not stop the fact that the array is variable.

Array data structure facie FIG.

Array variable that is just a reference on the stack, the body structure of the array in heap heap.

String class with a final modification of value, except to say this is called value in the stack reference address immutable. He did not say the pile of array data itself immutable. Look at the following example,

final int[] value={1,2,3} ;
int[] another={4,5,6};
 value=another;    //编译器报错,final不可变 value用final修饰,编译器不允许我把value指向堆区另一个地址。
但如果我直接对数组元素动手,分分钟搞定。

 final int[] value={1,2,3};
 value[2]=100;  //这时候数组里已经是{1,2,100}   所以String是不可变,关键是因为SUN公司的工程师。
 在后面所有String的方法里很小心的没有去动Array里的元素,没有暴露内部成员字段。private final char value[]这一句里,private的私有访问权限的作用都比final大。而且设计师还很小心地把整个String设成final禁止继承,避免被其他人继承后破坏。所以String是不可变的关键都在底层的实现,而不是一个final。考验的是工程师构造数据类型,封装数据的功力。 
复制代码

Immutable What are the benefits?

The simplest reason is for safety. Look at the following scenario (some critics reacted example is not clear enough now to be written out), back after a function appendStr String parameter immutable plus some "bbb" () returns. appendSb () is responsible for the variable back StringBuilder plus "bbb".

The following summarizes the immutability of String.

1 modified final first class only guarantee can not be inherited, and the object of this class address in the heap will not be changed.

2 but holds a String object reference itself can be changed, such as he can point to other objects.

3 final modified char array to ensure that the references can not change char array. However, the value may be modified by char [0] = 'a'. However, the method does not provide internal String to complete this operation, the String is immutable package based on the code and access control.

for example

final class Fi {
    int a;
    final int b = 0;
    Integer s;

}
final char[]a = {'a'};
final int[]b = {1};
@Test
public void final修饰类() {
    //引用没有被final修饰,所以是可变的。
    //final只修饰了Fi类型,即Fi实例化的对象在堆中内存地址是不可变的。
    //虽然内存地址不可变,但是可以对内部的数据做改变。
    Fi f = new Fi();
    f.a = 1;
    System.out.println(f);
    f.a = 2;
    System.out.println(f);
    //改变实例中的值并不改变内存地址。
复制代码

Fi ff = f;
//让引用指向新的Fi对象,原来的f对象由新的引用ff持有。
//引用的指向改变也不会改变原来对象的地址
f = new Fi();
System.out.println(f);
System.out.println(ff);

}
复制代码

Where fa is to be understood that modifications to char [0] = 'a' such operations. Only the data values ​​change, does not change the memory value.

String commonly used tools

Problem Description Many times we need to fix a lot of string operations, and these operations and no pre-set in the JDK / JRE in, so we thought apache-commons component, but it can not fully cover the needs of our business, so a lot of time or to write their own point code, the following is some common components based on apache-commons wrote:

MAVEN依赖
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>${commons-lang3.version}</version>
 </dependency>
复制代码

Code achievements

public class StringUtils extends org.apache.commons.lang3.StringUtils {

/** 值为"NULL"的字符串 */
private static final String NULL_STRING = "NULL";

private static final char SEPARATOR = '_';
复制代码

/**
 * 满足一下情况返回true<br/>
 * ①.入参为空
 * ②.入参为空字符串
 * ③.入参为"null"字符串
 *
 * @param string 需要判断的字符型
 * @return boolean
 */
public static boolean isNullOrEmptyOrNULLString(String string) {
    return isBlank(string) || NULL_STRING.equalsIgnoreCase(string);
}

/**
 * 把字符串转为二进制码<br/>
 * 本方法不会返回null
 *
 * @param str 需要转换的字符串
 * @return 二进制字节码数组
 */
public static byte[] toBytes(String str) {
    return isBlank(str) ? new byte[]{} : str.getBytes();
}

/**
 * 把字符串转为二进制码<br/>
 * 本方法不会返回null
 *
 * @param str     需要转换的字符串
 * @param charset 编码类型
 * @return 二进制字节码数组
 * @throws UnsupportedEncodingException 字符串转换的时候编码不支持时出现
 */
public static byte[] toBytes(String str, Charset charset) throws UnsupportedEncodingException {
    return isBlank(str) ? new byte[]{} : str.getBytes(charset.displayName());
}

/**
 * 把字符串转为二进制码<br/>
 * 本方法不会返回null
 *
 * @param str     需要转换的字符串
 * @param charset 编码类型
 * @param locale  编码类型对应的地区
 * @return 二进制字节码数组
 * @throws UnsupportedEncodingException 字符串转换的时候编码不支持时出现
 */
public static byte[] toBytes(String str, Charset charset, Locale locale) throws UnsupportedEncodingException {
    return isBlank(str) ? new byte[]{} : str.getBytes(charset.displayName(locale));
}

/**
 * 二进制码转字符串<br/>
 * 本方法不会返回null
 *
 * @param bytes 二进制码
 * @return 字符串
 */
public static String bytesToString(byte[] bytes) {
    return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes);
}

/**
 * 二进制码转字符串<br/>
 * 本方法不会返回null
 *
 * @param bytes   二进制码
 * @param charset 编码集
 * @return 字符串
 * @throws UnsupportedEncodingException 当前二进制码可能不支持传入的编码
 */
public static String byteToString(byte[] bytes, Charset charset) throws UnsupportedEncodingException {
    return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes, charset.displayName());
}

/**
 * 二进制码转字符串<br/>
 * 本方法不会返回null
 *
 * @param bytes   二进制码
 * @param charset 编码集
 * @param locale  本地化
 * @return 字符串
 * @throws UnsupportedEncodingException 当前二进制码可能不支持传入的编码
 */
public static String byteToString(byte[] bytes, Charset charset, Locale locale) throws UnsupportedEncodingException {
    return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes, charset.displayName(locale));
}

/**
 * 把对象转为字符串
 *
 * @param object 需要转化的字符串
 * @return 字符串, 可能为空
 */
public static String parseString(Object object) {
    if (object == null) {
        return null;
    }
    if (object instanceof byte[]) {
        return bytesToString((byte[]) object);
    }
    return object.toString();
}

/**
 * 把字符串转为int类型
 *
 * @param str 需要转化的字符串
 * @return int
 * @throws NumberFormatException 字符串格式不正确时抛出
 */
public static int parseInt(String str) throws NumberFormatException {
    return isBlank(str) ? 0 : Integer.parseInt(str);
}

/**
 * 把字符串转为double类型
 *
 * @param str 需要转化的字符串
 * @return double
 * @throws NumberFormatException 字符串格式不正确时抛出
 */
public static double parseDouble(String str) throws NumberFormatException {
    return isBlank(str) ? 0D : Double.parseDouble(str);
}

/**
 * 把字符串转为long类型
 *
 * @param str 需要转化的字符串
 * @return long
 * @throws NumberFormatException 字符串格式不正确时抛出
 */
public static long parseLong(String str) throws NumberFormatException {
    return isBlank(str) ? 0L : Long.parseLong(str);
}

/**
 * 把字符串转为float类型
 *
 * @param str 需要转化的字符串
 * @return float
 * @throws NumberFormatException 字符串格式不正确时抛出
 */
public static float parseFloat(String str) throws NumberFormatException {
    return isBlank(str) ? 0L : Float.parseFloat(str);
}

/**
 * 获取i18n字符串
 *
 * @param code
 * @param args
 * @return
 */
public static String getI18NMessage(String code, Object[] args) {
    //LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class);
    //HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    //Locale locale = localLocaleResolver.resolveLocale(request);
    //return SpringContextHolder.getApplicationContext().getMessage(code, args, locale);
    return "";
}

/**
 * 获得用户远程地址
 *
 * @param request 请求头
 * @return 用户ip
 */
public static String getRemoteAddr(HttpServletRequest request) {
    String remoteAddr = request.getHeader("X-Real-IP");
    if (isNotBlank(remoteAddr)) {
        remoteAddr = request.getHeader("X-Forwarded-For");
    } else if (isNotBlank(remoteAddr)) {
        remoteAddr = request.getHeader("Proxy-Client-IP");
    } else if (isNotBlank(remoteAddr)) {
        remoteAddr = request.getHeader("WL-Proxy-Client-IP");
    }
    return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
}

/**
 * 驼峰命名法工具
 *
 * @return toCamelCase(" hello_world ") == "helloWorld"
 * toCapitalizeCamelCase("hello_world") == "HelloWorld"
 * toUnderScoreCase("helloWorld") = "hello_world"
 */
public static String toCamelCase(String s, Locale locale, char split) {
    if (isBlank(s)) {
        return "";
    }

    s = s.toLowerCase(locale);

    StringBuilder sb = new StringBuilder();
    for (char c : s.toCharArray()) {
        sb.append(c == split ? Character.toUpperCase(c) : c);
    }

    return sb.toString();
}

public static String toCamelCase(String s) {
    return toCamelCase(s, Locale.getDefault(), SEPARATOR);
}

public static String toCamelCase(String s, Locale locale) {
    return toCamelCase(s, locale, SEPARATOR);
}

public static String toCamelCase(String s, char split) {
    return toCamelCase(s, Locale.getDefault(), split);
}

public static String toUnderScoreCase(String s, char split) {
    if (isBlank(s)) {
        return "";
    }

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        boolean nextUpperCase = (i < (s.length() - 1)) && Character.isUpperCase(s.charAt(i + 1));
        boolean upperCase = (i > 0) && Character.isUpperCase(c);
        sb.append((!upperCase || !nextUpperCase) ? split : "").append(Character.toLowerCase(c));
    }

    return sb.toString();
}

public static String toUnderScoreCase(String s) {
    return toUnderScoreCase(s, SEPARATOR);
}

/**
 * 把字符串转换为JS获取对象值的三目运算表达式
 *
 * @param objectString 对象串
 *                     例如:入参:row.user.id/返回:!row?'':!row.user?'':!row.user.id?'':row.user.id
 */
public static String toJsGetValueExpression(String objectString) {
    StringBuilder result = new StringBuilder();
    StringBuilder val = new StringBuilder();
    String[] fileds = split(objectString, ".");
    for (int i = 0; i < fileds.length; i++) {
        val.append("." + fileds[i]);
        result.append("!" + (val.substring(1)) + "?'':");
    }
    result.append(val.substring(1));
    return result.toString();
}
复制代码

}
复制代码

Reference article

https://blog.csdn.net/qq_34490018/article/details/82110578https://www.runoob.com/java/java-string.htmlhttps://www.cnblogs.com/zhangyinhua/p/7689974.htmlhttps://blog.csdn.net/sinat_21925975/article/details/86493248https://www.cnblogs.com/niew/p/9597379.html

Micro-channel public number

Java technology rivers and lakes

If you want to focus on my real time updated articles and dry sharing, you can focus on my public number of rivers and lakes] [Java technology Java, a technical engineer Ali station, the author Huang oblique, focused Java related technologies: SSM, SpringBoot , MySQL, distributed, middleware, cluster, Linux, network, multi-threaded, occasionally speaking point Docker, ELK, as well as dry goods and technology to share the learning experience, committed to the full Java stack development!

Java engineers required Learning Resources: Some Java engineers common learning resources, the number of public attention, background replies keyword "Java" to get free no routine.

My public number

Personal Public Number: Huang oblique

The author is Master 985, ants gold dress JAVA engineer, specializing in JAVA backend technology stack: SpringBoot, MySQL, distributed, middleware, services, but also understand the point of investment banking, occasionally speaking point algorithms and theoretical basis of computer, keep learning and writing, believe in the power of lifelong learning!

Programmers 3T Technology Learning Resources: Some programmers learning resources spree technology, the number of public attention, background replies keyword "data" can get free no routine.

Guess you like

Origin juejin.im/post/5d8b57545188253e5445311a