Как логику которая создает annagram для одного слова вынести в отдельный метод?

import java.util.Arrays;
import java.util.stream.Collectors;

public class App {
    public static void main(String[] args) {
        String input = "abcd1 efg!h";

         String anagram = Arrays.stream(input.split(" ")).map(str -> {
        
            char[] chars = str.toCharArray();
            int i = 0;
            int j = chars.length - 1;
            while (i < j) {
                if (Character.isLetter(chars[i]) && Character.isLetter(chars[j])) {
                    char tmp = chars[i];
                    chars[i] = chars[j];
                    chars[j] = tmp;
                    i++;
                    j--;
                } else if (!Character.isLetter(chars[i]))
                    i++;
                else
                    j--;
            }
            return new String(chars);
        }).collect(Collectors.joining(" "));
        System.out.println(anagram);
    }
}

Ответы (1 шт):

Автор решения: Nowhere Man

Не совсем понятно, в чём проблема выполнить следующие шаги:

  1. Вынести содержимое лямбды в .map(str -> {...}) в нужный метод, который можно назвать reverseLetters, так как он переставляет буквы во входной строке в обратном порядке
  2. Заменить код лямбды ссылкой на этот метод.
import java.util.*;
import java.util.stream.*;

public class App {
    
    static String reverseLetters(String str) {
        char[] chars = str.toCharArray();
        int i = 0;
        int j = chars.length - 1;
        while (i < j) {
            if (Character.isLetter(chars[i]) && Character.isLetter(chars[j])) {
                char tmp = chars[i];
                chars[i] = chars[j];
                chars[j] = tmp;
                i++;
                j--;
            } else if (!Character.isLetter(chars[i]))
                i++;
            else
                j--;
        }
        return new String(chars);
    }

    public static void main(String args[]) {
        String input = "abcd1 efg!h";

        String anagram = Arrays.stream(input.split(" "))
            .map(App::reverseLetters)
            .collect(Collectors.joining(" "));

        System.out.println(anagram);
    }
}

Результат такой же как и до рефакторинга:

dcba1 hgf!e

Если же задача в том, чтобы переработать представленный метод и получить рандомизированные анаграммы со случайными перестановками только букв, это можно реализовать при помощи алгоритма Фишера - Йетса в отдельном методе:

static String shuffleLetters(String str) {
    char[] arr = str.toCharArray();
    Random rand = new Random();
    
    for (int i = arr.length; i-- > 0;) {
        if (!Character.isLetter(arr[i])) {
            continue; // пропускаем не-буквенные символы
        }
        int j;
        // ищем случайный буквенный символ
        while (!Character.isLetter(arr[j = rand.nextInt(i + 1)]));
        
        char t = arr[j];
        arr[j] = arr[i];
        arr[i] = t;
    }
    return new String(arr);
}
// ...

Тест на 5 попыток:

String input = "abcd1 efg!h";

for (int i = 0; i < 5; i++) {
    String anagram = Arrays.stream(input.split(" "))
        .map(App::shuffleLetters)
        .collect(Collectors.joining(" "));

    System.out.println((i + 1) + ": " + anagram);
}

Результат:

1: bdac1 feh!g
2: dbca1 gef!h
3: adcb1 hgf!e
4: dacb1 fhg!e
5: abdc1 gfe!h
→ Ссылка