OMG, 12 exquisite Java string operation tips, learn it

String can be said to be the most representative class in Java. It seems that there is no one. Ha, it's like Li Jiaqi in the live broadcasting industry, Li birthday in the talk show, and the status of first-class big brother. I have to admit that I have been brushing too much at the recent roast conference. My mind is full of those passages. I can't help writing articles. I really can't help myself.

Since the string is the most commonly used, it means that the interviewer likes to ask some string coding skills to test whether the candidate is skilled and solid, right?

This time, I'll take stock of 12 exquisite Java string operation tips to help you improve. Before checking the answers I give, you'd better try it by yourself. It doesn't matter if you can't write the answers. Think about it first to see if there are solutions in your knowledge base. If there are some, it's just a review. If not, don't worry. Just learn it again.

01. How to get different characters and their number in a string?

This problem can be divided into two steps. The first step is to find out different characters, and the second step is to count their number. It seems a little nonsense, isn't it? Let me have an answer first.

public class DistinctCharsCount {
    public static void main(String[] args) {
        printDistinctCharsWithCount("itwanger");
        printDistinctCharsWithCount("chenmowanger");
    }

    private static void printDistinctCharsWithCount(String input) {
        Map<Character, Integer> charsWithCountMap = new LinkedHashMap<>();

        for (char c : input.toCharArray()) {
            Integer oldValue = charsWithCountMap.get(c);

            int newValue = (oldValue == null) ? 1 :
                    Integer.sum(oldValue, 1);

            charsWithCountMap.put(c, newValue);
        }
        System.out.println(charsWithCountMap);
    }
}

The result of the program output is:

{i=1, t=1, w=1, a=1, n=1, g=1, e=1, r=1}
{c=1, h=1, e=2, n=2, m=1, o=1, w=1, a=1, g=1, r=1}

Let's talk about my idea:

1) Declare a LinkedHashMap , you can also use HashMap, but the former can maintain the order of string splitting, and the result looks more clear at a glance.

Why use Map? Because Map key s are not allowed to be repeated, the number of repeated characters can be accumulated.

2) Split the string into characters for traversal.

3) If the key is null, it indicates that its number should be + 1; Otherwise, add + 1 to the previous value, and then put it back into the Map, which overwrites the previous number of characters.

It's clear, isn't it? I can't help clapping myself.

After JDK 8, a powerful method merge() has been added to Map to assign values to multiple keys at one time:

private static void printDistinctCharsWithCountMerge(String input) {
    Map<Character, Integer> charsWithCountMap = new LinkedHashMap<>();

    for (char c : input.toCharArray()) {
        charsWithCountMap.merge(c, 1, Integer::sum);
    }
    System.out.println(charsWithCountMap);
}

Is it great? One line of code. The first parameter is the key, the second parameter is the value, and the third parameter is a BiFunction, which means that if the key already exists, the new value will be calculated again according to the BiFunction.

If the character appears for the first time, it is assigned a value of 1; Otherwise, take the previous value sum 1.

02. How to reverse a string?

If students are familiar with StringBuilder and StringBuffer, this problem is very simple. Just reverse(), right?

public class ReverseAString {
    public static void main(String[] args) {
        reverseInputString("Silent King II");
    }
    private static void reverseInputString(String input) {
        StringBuilder sb = new StringBuilder(input);
        String result = sb.reverse().toString();
        System.out.println(result);
    }
}

The output results are as follows:

Er Wang Mo Shen

To add another word, StringBuffer is very similar to StringBuilder. The former is synchronous. All public methods are added with the synchronized keyword, which can be used in multithreading; The latter is unsynchronized and has no synchronized keyword, so the performance is better. If there is no concurrency requirement, use StringBuilder.

03. How to judge whether a string is symmetrical?

What do you mean? It's like a string, folded back and forth, is symmetrical. It's like standing in front of the mirror and seeing yourself with a jade tree facing the wind and a closed moon ashamed of flowers.

public class PalindromeString {
    public static void main(String[] args) {

        checkPalindromeString("Silent King II");
        checkPalindromeString("Silent King II Er Wang Mo Shen");
    }

    private static void checkPalindromeString(String input) {
        boolean result = true;
        int length = input.length();
        for (int i = 0; i < length / 2; i++) {
            if (input.charAt(i) != input.charAt(length - i - 1)) {
                result = false;
                break;
            }
        }
        System.out.println(input + " Symmetrical? " + result);

    }
}

The output results are as follows:

Silent King II Symmetrical? false
Silent King II Er Wang Mo Shen Symmetrical? true

Let's talk about my idea: to judge whether the string is symmetrical after folding in half, it is very simple to split it from the middle. The first character is compared with the last character. Once the unequal one is found, it returns false.

Pay attention to three points:

1) The subscript of the for loop starts at 0 and ends at length/2.

2) Subscripts I and length-i-1 are symmetric.

3) Once false, break.

04. How to delete all the specified characters?

The string class does not provide the remove() method, but provides the replaceAll() method. You can do this by replacing the specified character with a blank character, right?

public class RemoveCharFromString {
    public static void main(String[] args) {
        removeCharFromString("Silent King II"'two');
        removeCharFromString("chenmowanger"'n');

    }

    private static void removeCharFromString(String input, char c) {
        String result = input.replaceAll(String.valueOf(c), "");
        System.out.println(result);
    }
}

The output results are as follows:

Silent King
chemowager

05. How to prove that a string is immutable?

I wrote two articles about the immutability of strings, and I was going to vomit at the end. But there are still some students who don't understand. Someone wrote to me every other period of time, so I had to put the previous article in my favorites. When I asked, I sent him the link.

There are many factors that cause this confusion. For example, is Java value passing or reference passing? What is a string constant pool?

I have to talk again this time. Although I'm tired of it, I still have to prove it!

public class StringImmutabilityTest {
    public static void main(String[] args) {
        String s1 = "Silent King II";
        String s2 = s1;
        System.out.println(s1 == s2);

        s1 = "Silent King three";
        System.out.println(s1 == s2);

        System.out.println(s2);
    }
}

The output results are as follows:

true
false
Silent King II

1) String s1 = "silent King 2", Java creates the object of "silent King 2" in the string constant pool, and assigns the address reference to s1

2) String s2 = s1, s2 and s1 point to the same address reference - the "silent King 2" in the constant pool.

Therefore, s1 == s2 is true at this time.

3) s1 = "silent king 3", Java creates the object of "silent king 3" in the string constant pool and assigns the address reference to s1, but s2 still points to the address reference of the string object of "silent King 2".

Therefore, at this time, s1 == s2 is false, and the output result of s2 is "silent King 2", which proves that the string is immutable.

06. How to count the number of words in a string?

What about this question? Mainly for the case of English strings. Although Chinese strings can also have white space characters, there is no word.

public class CountNumberOfWordsInString {
    public static void main(String[] args) {
        countNumberOfWords("My name is Wanger");
        countNumberOfWords("I Love Java Programming");
        countNumberOfWords(" Java    is  very   important ");
    }

    private static void countNumberOfWords(String line) {
        String trimmedLine = line.trim();
        int count = trimmedLine.isEmpty() ? 0 : trimmedLine.split("\\s+").length;

        System.out.println(count);
    }
}

The output results are as follows:

4
4
4

The split() method can split the string. The parameters can be not only spaces, but also blank characters replaced by regular expressions (multiple spaces and tabs); The returned is an array. The number of words can be obtained through length.

If you are interested in the split() method, you can check an article I wrote before, which is full and rich.

Eh, splitting a string is so particular

07. How to check that the characters in two strings are the same?

How to understand this problem? For example, the strings "silent King Er" and "Shen King Er Mo" use the same characters, right? For example, the characters used in the string "silent King 2" and "silent king 3" are different, understand?

public class CheckSameCharsInString {
    public static void main(String[] args) {
        sameCharsStrings("Silent King II""Shen Wang Ermo");
        sameCharsStrings("Silent King II""Silent King three");
    }

    private static void sameCharsStrings(String s1, String s2) {
        Set<Character> set1 = s1.chars().mapToObj(c -> (char) c).collect(Collectors.toSet());
        System.out.println(set1);
        Set<Character> set2 = s2.chars().mapToObj(c -> (char) c).collect(Collectors.toSet());
        System.out.println(set2);
        System.out.println(set1.equals(set2));
    }
}

The output results are as follows:

[Silence, sink, king, two]
[Silence, sink, king, two]
true
[Silence, sink, king, two]
[Silence, sink, three, king]
false

The above code uses the Stream stream Stream. It looks strange, but it is easy to understand. It is to break the string into characters and collect them into a set. Set is a set that does not allow duplicate elements, so it collects different characters in the string.

08. How to judge whether a string contains another string?

This question is a little simple, isn't it? The last one also used Stream stream flow, so this question will be directly given points? Don't doubt yourself, just use the contains() method of the string class.

public class StringContainsSubstring {
    public static void main(String[] args) {
        String s1 = "Silent King II";
        String s2 = "silent";

        System.out.println(s1.contains(s2));
    }
}

The output results are as follows:

true

The contents() method actually calls the indexOf() method:

public boolean contains(CharSequence s) {
    return indexOf(s.toString()) >= 0;
}

09. How to exchange two strings without the third variable?

That's a little interesting, isn't it? In particular, the precondition is not to use the third variable.

public class SwapTwoStrings {
    public static void main(String[] args) {
        String s1 = "silent";
        String s2 = "WangTwo ";

        s1 = s1.concat(s2);
        s2 = s1.substring(0,s1.length()-s2.length());
        s1 = s1.substring(s2.length());

        System.out.println(s1);
        System.out.println(s2);
    }
}

The output results are as follows:

WangTwo 
silent

Let's talk about my idea:

1) The concat() method is used to splice the two strings together.

2) Then take out the second string and the first string respectively through the substring() method.

10. How do I find the first non repeating character in a string?

Let's take a look at this problem with the last example. For example, in the string "silence Wang Shen silence 2", the first non repeating character is "Wang", right? Because "Shen" repeats, "Mo" repeats.

public class FindNonRepeatingChar {
    public static void main(String[] args) {
        System.out.println(printFirstNonRepeatingChar("Silence Wang Shen silence II"));
        System.out.println(printFirstNonRepeatingChar("Silent Wang Shen"));
        System.out.println(printFirstNonRepeatingChar("Heavy"));
    }

    private static Character printFirstNonRepeatingChar(String string) {
        char[] chars = string.toCharArray();

        List<Character> discardedChars = new ArrayList<>();

        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];

            if (discardedChars.contains(c))
                continue;

            for (int j = i + 1; j < chars.length; j++) {
                if (c == chars[j]) {
                    discardedChars.add(c);
                    break;
                } else if (j == chars.length - 1) {
                    return c;
                }
            }
        }
        return null;
    }
}

The output results are as follows:

king
Silence
null

Let's talk about my idea:

1) Splits a string into an array of characters.

2) Declare a List and put duplicate characters in it.

3) The for loop of the outer layer starts from the first character. If it is already in the List, continue to the next round.

4) The nested for loop starts from the next character (j = i + 1) of the first character. If it finds a character that is repeated with the previous character, it will be added to the List and jump out of the inner loop; If the last (j == chars.length - 1) is not found, it is the first non repeating character, right?

11. How do I check that a string contains only numbers?

One silly solution is to use long Parselong (string) forcibly converts a string. If it cannot be converted into an integer, it must not contain only numbers, right?

But this method is also too undesirable, so we have to use regular expressions instead.

public class CheckIfStringContainsDigitsOnly {
    public static void main(String[] args) {
        digitsOnlyString("123 Silent King II");
        digitsOnlyString("123");

    }

    private static void digitsOnlyString(String string) {
        if (string.matches("\\d+")) {
            System.out.println("String containing only numbers:" + string);
        }
    }
}

The output results are as follows:

Number only: 123

12. How to realize deep copy of string?

Because strings are immutable, you can directly use the "=" operator to copy one string to another without affecting each other.

public class JavaStringCopy {
    public static void main(String args[]) {
        String str = "Silent King II";
        String strCopy = str;

        str = "Silent King three";
        System.out.println(strCopy);
    }
}

The output results are as follows:

Silent King II

This example is almost the same as the previous example that proved that the string is immutable, right? This is really because the string is immutable. If it is a variable object, you should pay attention to the deep copy. It is best to use the new keyword to return a new object.

public Book getBook() {
    Book clone = new Book();
    clone.setPrice(this.book.getPrice());
    clone.setName(this.book.getName());
    return clone;
}

For immutable objects, please click the link below to see an article I wrote before.

If I don't understand the immutable class this time, I'll do it

last

I hope these 12 exquisite string manipulation tips can help you consolidate a wave of foundation. Anyway, I have consolidated a wave again. It looks very fruitful. It feels like "a group of elves dancing in my mind". Just learn it!

I'm silent Wang Er, a programmer who lived in Luoyang, the ancient capital of the nine dynasties. Attention can improve learning efficiency. Thank you for your three company support, Ollie 🌹.

Note: if there are any questions in the article, you are welcome to correct them mercilessly.

If you think the article is helpful to you, you are welcome to search "silent King 2" on wechat to read it for the first time. Reply to the keyword "Xiaobai" and get my 40000 + word version 2.0 of "Java Xiaobai from getting started to being presumptuous" for free; This article GitHub github.com/itwanger Included, welcome star.

Tags: Java string

Posted by KirstyScott on Fri, 20 May 2022 08:38:27 +0300