Рубрики
Без рубрики

Как изменить строку в Java

В Java мы можем использовать `StringBuilder(str).reverse()` для обращения строки.

В этой статье мы покажем вам несколько способов обращения строки в Java.

  • Строковый конструктор(str).обратный()
  • символ[] зацикливание и замена значений.
  • байт зацикливание и замена значений.
  • Apache общее достояние-lang3

Для разработки всегда выбирается стандартный StringBuilder(str).обратный() API.

В образовательных целях мы можем изучить методы char[] и байт , в них использовались методы обмена значениями и побитового сдвига, которые очень полезны для понимания того, что происходит за черным ящиком обратного API.

1. Строковый конструктор(str).обратный()

В Java мы можем использовать StringBuilder(str).reverse() для обращения строки.

package com.mkyong.crypto.bytes;

public class ReverseString1 {

    public static void main(String[] args) {

        String str = "Reverse a String in Java";

        StringBuilder sb = new StringBuilder(str).reverse();

        System.out.println(sb.toString());

    }

}

Выход

  avaJ ni gnirtS a esreveR

2. Символ[]

Сначала мы преобразуем строку в массив символов и зацикливаем массив символов один за другим и меняем значения местами с помощью временной переменной.

package com.mkyong.utils;

public class ReverseString2 {

    public static void main(String[] args) {

        String str = "Hello World";
        System.out.println(reverse(str));         //  dlroW olleH

    }

    public static String reverse(String input) {

        if (input == null || input.length() < 0)
            throw new IllegalArgumentException("Please provide an input!");

        char[] result = input.toCharArray();

        int startIndex = 0;
        int endIndex = result.length - 1;
        char temp;

        for (; endIndex > startIndex; startIndex++, endIndex--) {
            temp = result[startIndex];
            result[startIndex] = result[endIndex];
            result[endIndex] = temp;
        }

        return new String(result);
    }

}

Описанному выше алгоритму требуется 5 циклов (длина/2), чтобы перевернуть строку “Привет, мир”.

------------------------------------
H  e  l  l  o     W  o  r  l  d
------------------------------------
0  1  2  3  4  5  6  7  8  9  10
------------------------------------

Loop #1 - Swap index 0 <-> index 10
------------------------------------
{d}  e  l  l  o     W  o  r  l  {H}
------------------------------------
{0}  1  2  3  4  5  6  7  8  9  {10}
------------------------------------

Loop #2 - Swap index 1 <-> index 9
------------------------------------
d  {l}  l  l  o     W  o  r  {e}  H
------------------------------------
0  {1}  2  3  4  5  6  7  8  {9}  10
------------------------------------

Loop #3 - Swap index 2 <-> index 8
------------------------------------
d  l  {r}  l  o     W  o  {l}  e  H
------------------------------------
0  1  {2}  3  4  5  6  7  {8}  9  10
------------------------------------

Loop #4 - Swap index 3 <-> index 7
------------------------------------
d  l  r  {o}  o     W  {l}  l  e  H
------------------------------------
0  1  2  {3}  4  5  6  {7}  8  9  10
------------------------------------

Loop #5 - Swap index 4 <-> index 6
------------------------------------
d  l  r  o  {W}     {o}  l  l  e  H
------------------------------------
0  1  2  3  {4}  5  {6}  7  8  9  10
------------------------------------

3. Байт[] – строковый конструктор(str).обратный()

Приведенный ниже фрагмент кода аналогичен StringBuilder(str).reverse() для обращения строки (за исключением UTF16).

package com.mkyong.crypto.bytes;

import java.nio.charset.StandardCharsets;

public class ReverseString3 {

    public static void main(String[] args) {

        String str = "Hello World";
        System.out.println(reverse(str));

    }

    public static String reverse(String input) {

        if (input == null || input.length() < 0)
            throw new IllegalArgumentException("Please provide an input!");

        byte[] val = input.getBytes(StandardCharsets.UTF_8);
        int length = val.length - 1;

        for (int start = (length - 1) >> 1; start >= 0; start--) {
            int end = length - start;
            byte temp = val[start];
            val[start] = val[end];
            val[end] = temp;

            // debugging
            //System.out.println(String.format("start=%s, end=%s", start, end));
        }

        return new String(val);
    }

}

Самая запутанная часть – это оператор сдвига бита вправо (длина - 1) >> 1 , что это значит?

Просмотрите следующий 8-битный пример, можете ли вы узнать шаблон?

System.out.println(10>>1);  //  10 -> 5
0000 1010   = 10
0000 0101|0 = 10 >> 1 = 5

System.out.println(4>>1);   //  4 -> 2
0000 0100   = 4
0000 0010|0 = 4 >> 1 = 2

System.out.println(100>>1); //  100 -> 50
0110 0100   = 100
00110 010|0 = 100 >> 1 = 50

System.out.println(7>>1);   //  7 -> 3
0000 0111   = 7
0000 0011|1 = 7 >> 1 = 3

Для числа при каждом сдвиге вправо на 1 бит сумма будет уменьшаться вдвое и округляться в меньшую сторону. Это (длина - 1) >> 1 пытается найти среднюю точку строки.

number >> 1 = round_down(number/2) or Math.flooa(number/2)

И обмен значениями начинается изнутри и расширяется наружу.

  for (int start = (length - 1) >> 1; start >= 0; start--) {
      int end = length - start;
      byte temp = val[start];
      val[start] = val[end];
      val[end] = temp;
  }
------------------------------------
H  e  l  l  o     W  o  r  l  d
------------------------------------
0  1  2  3  4  5  6  7  8  9  10
------------------------------------

Loop #1 - Swap index 4 <-> index 6
------------------------------------
H  e  l  l  {W}     {o}  o  r  l  d
------------------------------------
0  1  2  3  {4}  5  {6}  7  8  9  10
------------------------------------

Loop #2 - Swap index 3 <-> index 7
------------------------------------
H  e  l  {o}  W     o  {l}  r  l  d
------------------------------------
0  1  2  {3}  4  5  6  {7}  8  9  10
------------------------------------

Loop #3 - Swap index 2 <-> index 8
------------------------------------
H  e  {r}  o  W     o  l  {l}  l  d
------------------------------------
0  1  {2}  3  4  5  6  7  {8}  9  10
------------------------------------

Loop #4 - Swap index 1 <-> index 9
------------------------------------
H  {l}  r  o  W     o  l  l  {e}  d
------------------------------------
0  {1}  2  3  4  5  6  7  8  {9}  10
------------------------------------

Loop #5 - Swap index 0 <-> index 10
------------------------------------
{d}  l  r  o  W     o  l  l  e  {H}
------------------------------------
{0}  1  2  3  4  5  6  7  8  9  {10}
------------------------------------

4. Общий доступ Apache-lang3

Для библиотеки Apache commons-lang3 мы можем использовать StringUtils.reverse для обращения строки и StringUtils.reversedelimited для обращения слов.

  
      org.apache.commons
      commons-lang3
      3.10
  
package com.mkyong.utils;

import org.apache.commons.lang3.StringUtils;

public class ReverseString3 {

    public static void main(String[] args) {

        System.out.println(StringUtils.reverse("Hello World Java"));                // reverse string

        System.out.println(StringUtils.reverseDelimited("Hello World Java", ' '));  // reverse words

    }
}

Выход

avaJ dlroW olleH

Java World Hello

Просмотрите исходный код, внутренне, Apache commons-lang3 использует new StringBuilder(str).reverse() для изменения строки.

package org.apache.commons.lang3;

  public class StringUtils {

  public static String reverse(final String str) {
      if (str == null) {
          return null;
      }
      return new StringBuilder(str).reverse().toString();
  }

  //...
}

Рекомендации

Оригинал: “https://mkyong.com/java/how-to-reverse-a-string-in-java/”