Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

12 tips for Java string manipulation!


May 31, 2021 Article blog


Table of contents


The article comes from the public number: Silent King II, author Silence King II

Strings are arguably the most representative class in Java, and there doesn't seem to be one of them, it's like Li Jiaqi in the live stream, Li's birthday on a talk show, and first-class big brother status. I have to admit, the recent spitting session brush more, the mind is full of those paragraphs, writing articles are a little involuntary, really, hands can not help themselves ah.

Since strings are the most commonly used, that means the interviewer is good at this mouthful, like to ask some string coding skills, to test whether the candidate is skilled, solid foundation, right?

So this time, I'll take stock of 12 exquisite Java string manipulation tips to help you improve. Before you look at the answers I give, it's best to try it yourself, it doesn't matter if you can't write the answer, think about it first, see if you already have a solution in your knowledge base, and if so, review it warmly, if not, don't worry, just learn it again.

01. How do I get different characters and their numbers in a string?

This question can be disassembled into two steps, the first step, to find out the different characters, the second step, to count their number. I t seems like a bit of crap, doesn'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}

Tell me what I think:

1) Declare a LinkedHashMap, which can also be used with HashMap, but the former can maintain the order in which strings are split, and the results look more at a glance.

Why use Map? Because map's key is not allowed to repeat, it is possible to add up the number of duplicate characters.

2) Split the string into characters and traverse it.

3) If the key is null, it means that the number of characters is 1, otherwise, it is on the previous value, and then put back into map, which overrides the number of previous characters.

The idea is clear, isn't it? I can't help but give myself a slap.

Well, after JDK 8, Map added a great method merge() to assign multiple keys at once:

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 that great? O ne line of code is done. The first argument is a key, the second argument is a value, and the third argument is a BiFunction, which means that if the key already exists, the new value is recalculated according to BiFunction.

If the character appears for the first time, it is assigned a value of 1;

02, how to reverse the string?

If the students are familiar with StringBuilder and StringBuffer, the question is simple, and the direct reverse() is done, right?

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

The output looks like this:

编程狮

To put it another way, StringBuffer and StringBuilder are similar, with the former being synchronous, with all public methods with synchronized keyword, which can be used in multiple threads, and the latter being unsynchronized, without synchronized keyword, so better performance, without concurring requirements, use StringBuilder.

03, how to judge a string is symmetrical?

What do you mean? I t's like a string, folded back and forth, symmetrical. Just like you stand in front of the mirror, see a jade tree in the wind, closed moon shy flowers of their own.

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


        checkPalindromeString("编程狮");
        checkPalindromeString("编程狮 狮程编");
    }


    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 + " 对称吗? " + result);


    }
}

The output looks like this:

编程狮 对称吗? false
编程狮 狮程编 对称吗? true

Tell me about my idea: to determine whether a string is symmetrical after a trade-in, it's simple, split from the middle, the first character versus the last character, and once you find the one that doesn't, return false.

Note three things:

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

2) The subscripts i and length-i-1 are symmetrical.

3) Break once false.

04, how to delete all the specified characters that appear?

String classes don't provide remove() method, but they do, but they provide replaceAll() method, which you can do by replacing the specified character with a blank character, right?

public class RemoveCharFromString {
    public static void main(String[] args) {
        removeCharFromString("编程狮", '狮');
        removeCharFromString("bianchengshi", 'n');


    }


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

The output looks like this:

编程
biachegshi

05, how to prove that the string is immutable?

I've written two articles about string immutability, and I'm going to throw up at the end. But there will still be some students do not understand, every once in a while someone private letter me, I have to put the previous article into the favorites, when asked I will send him the link.

There are many factors that contribute to this confusion, such as whether Java is a value pass or a reference pass? What is a string constant pool?

This time have to talk, although bored, but still have to prove ah!

public class StringImmutabilityTest {
    public static void main(String[] args) {
        String s1 = "编程狮二";
        String s2 = s1;
        System.out.println(s1 == s2);


        s1 = "编程狮三";
        System.out.println(s1 == s2);


        System.out.println(s2);
    }
}

The output looks like this:

true
false
编程狮二

1) String s1 = "编程狮二" Java creates an object with the "Programming Lion II" string character in the string constant pool, and assigns an address reference to s1

2) String s2 = s1 s2 and s1 point to the same address reference - the "programming lion two" in the constant pool.

So, at this point, s1 is true.

3) s1 = "编程狮三" Java creates an object with the "Programming Lion III" string character in the string constant pool and assigns an address reference to s1, but s2 still points to the address reference of the "Programming Lion II" string of character objects.

Therefore, at this point s1 s2 is false, and the output of s2 is "Programming Lion II" to prove that the string is immutable.

06, how to count the number of words in the string?

What about this question? T his is mainly for the case of English strings. Although Chinese string can also have blank characters, there is no word to say.

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 looks like this:

4
4
4

split() method splits a string, and arguments can be not only spaces, but also blank characters (multiple length spaces, tabs) that regular expressions replace;

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

How do you understand this question? F or example, the strings "Silent King II" and "Shen Wang IImer" use the same characters, right? For example, the string "Silent King II" and "Silence King III" use different characters, understand it?

public class CheckSameCharsInString {
    public static void main(String[] args) {
        sameCharsStrings("编程狮", "狮编程");
        sameCharsStrings("编程狮王", "编程狮子");
    }


    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 looks like this:

[编, 程, 狮]
[编, 程, 狮]
true
[编, 程, 狮, 王]
[编, 程, 子, 狮]
false

The code above uses the Stream stream, which looks strange, but it's easy to understand that the string is split into characters and then collected into Set, a collection that doesn't allow duplicate elements, so the different characters in the string are collected.

08, how to judge that one string contains another string?

The question is a little simple, isn't it? T he previous one also used Stream Stream, and the question went straight to the score? Without doubting yourself, use the contains() method of the string class.

public class StringContainsSubstring {
    public static void main(String[] args) {
        String s1 = "编程狮";
        String s2 = "编程";


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

The output looks like this:

true

The contains() method is actually called inside the indexOf() method:

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

09. How do I exchange two strings without the third variable?

That's a bit of fun, isn't it? In particular, the third variable is not used.

public class SwapTwoStrings {
    public static void main(String[] args) {
        String s1 = "编程";
        String s2 = "狮";


        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 looks like this:

狮
编程

Tell me what I think:

1) Stitch the two strings together by concat() method.

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

10. How do I find the first character from a string that doesn't repeat?

Let's take the last example to understand the problem. F or example, the string "programming lion programming king", the first character that does not repeat is "lion", right? Because the "editor" repeats, the "process" repeats.

public class FindNonRepeatingChar {
    public static void main(String[] args) {
        System.out.println(printFirstNonRepeatingChar("编程狮编编程王"));
        System.out.println(printFirstNonRepeatingChar("编程狮编"));
        System.out.println(printFirstNonRepeatingChar("狮狮狮"));
    }


    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 looks like this:

狮
程
null

Tell me what I think:

1) Split the string into an array of characters.

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

3) The outer for loop, starting with the first character and, if already in The List, continues to the next round.

4) Nested for loop, traversed from the next character of the first character j = i + 1 and if it is found and repeated by the previous character, it is added to the List and jumps out of the inner loop, and if the last j == chars.length - 1 is not found, it is the first character that does not repeat, right?

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

There's a silly solution to using Long.parseLong(string) to strongly turn strings, and if it doesn't turn, it's definitely not just numbers, is it?

But this approach is also too undesirable, so it has to be replaced by a clever use of regular expressions.

public class CheckIfStringContainsDigitsOnly {
    public static void main(String[] args) {
        digitsOnlyString("123 编程狮");
        digitsOnlyString("123");


    }


    private static void digitsOnlyString(String string) {
        if (string.matches("\\d+")) {
            System.out.println("只包含数字的字符串:" + string);
        }
    }
}

The output looks like this:

只包含数字:123

12, how to achieve a deep copy of the string?

Because strings are immutable, you can copy one string directly to another using the "

public class JavaStringCopy {
    public static void main(String args[]) {
        String str = "编程狮王";
        String strCopy = str;


        str = "编程狮子";
        System.out.println(strCopy);
    }
}

The output looks like this:

编程狮王

This example is hardly different from the previous example that proved that strings are immutable, is it? This is true because the string is immutable, and if it is a variable object, the deep copy should be aware that it is best to return the new object using the new keyword.

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

At last

Hopefully these 12 exquisite string manipulation tips can help you consolidate a wave of foundation, anyway, I have re-consolidated a wave, very rewarding look, feel like "a bunch of elves dancing in my head", learn it right!

Here are 12 tips from W3Cschool编程狮 on Java string manipulation! Related to the introduction, I hope to help you.