В чём ошибка в задаче на Java?

Само замечание от преподавателя - StringBuilder используй только его экземпляр. Стринг создавать не нужно удали конкатенацию в цикле.

public static String printTextPerRole(String[] roles, String[] textLines) {
    StringBuilder textPerRole = new StringBuilder();
    
    for (String role : roles) {
        StringBuilder text = new StringBuilder();
        textPerRole.append(role).append(":").append("\n");
        
        for (int i = 0; i < textLines.length; i++) {
            if (textLines[i].startsWith(role + ":")) {
                textLines[i] = textLines[i].replaceFirst(role + ":", "");
                text.append(i + 1).append(")").append(textLines[i]).append("\n");
            }
        }
        
        if (text.length() > 0) {
            textPerRole.append(text);
        }
        textPerRole.append("\n");
    }
    
    return textPerRole.toString();
}

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

Автор решения: talex

Ожидается что-то вроде этого

public static String printTextPerRole(String[] roles, String[] textLines) {
    record V(int index, String value) {
    }
    Map<String, List<V>> map = new HashMap<>();
    for (int i = 0; i < textLines.length; i++) {
        int index = textLines[i].indexOf(':');
        String role = textLines[i].substring(0, index);
        String value = textLines[i].substring(index + 1);
        map.computeIfAbsent(role, ignore -> new ArrayList<>()).add(new V(i + 1, value));
    }
    StringBuilder textPerRole = new StringBuilder();
    for (String role : roles) {
        textPerRole.append(role).append(":").append("\n");
        for (V v : map.getOrDefault(role, List.of())) {
            textPerRole.append(v.index()).append(")").append(v.value()).append("\n");
        }
        textPerRole.append("\n");
    }
    return textPerRole.toString();
}
→ Ссылка
Автор решения: Nowhere Man

Вероятно, имелась в виду конкатенация role + ":", которая повторяется дважды во вложенном цикле и до этого выполняется добавление аналогичной строки перед вложенным циклом.

Поиск такой строки можно заменить двумя вызовами startsWith, а вместо replaceFirst(role + ":", "") обойтись substring(role.length() + 1).

Также можно избежать создания в цикле новых объектов StringBuilder и использовать метод setLength(0) для их очистки.

Исправленный вариант:

public static String printTextPerRole(String[] roles, String[] textLines) {
    StringBuilder textPerRole = new StringBuilder();
    StringBuilder text = new StringBuilder();

    for (String role : roles) {
        textPerRole.append(role).append(":\n");

        for (int i = 0; i < textLines.length; i++) {
            if (textLines[i].startsWith(role) && textLines[i].startsWith(":", role.length())) {
                textLines[i] = textLines[i].substring(role.length() + 1);
                text.append(i + 1).append(")").append(textLines[i]).append("\n");
            }
        }

        if (text.length() > 0) {
            textPerRole.append(text);
            text.setLength(0);
        }
        textPerRole.append("\n");
    }

    return textPerRole.toString();
}
→ Ссылка