Я пытаюсь рекурсивно разбить String
(хранится в ArrayList
) на фиксированное количество слов (не символов).
Например, предположим, у меня есть ArrayList
, который содержит следующие две String
фразы:
ArrayList<String> words = new ArrayList<String>();
words.add("key1 key2 key3 key4 key5 key6 key7");
words.add("key11 key12 key13 key14 key15 key16 key17");
И я хочу разбить на куски по 5 слов (int desiredListSize = 5;
) - это даст следующие два списка:
LIST 1:
word1 word2 word3 word4 word5
word2 word3 word4 word5 word6
word3 word4 word5 word6 word7
LIST 2:
word11 word12 word13 word14 word15
word12 word13 word14 word15 word16
word13 word14 word15 word16 word17
Каждый приведенный выше список будет затем добавлен в массив List of Lists, поэтому выходные данные будут иметь формат: ArrayList<ArrayList<String>()
Так далеко следующий фрагмент кода решает большую часть проблемы:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public static void splitListIntoWords()
{
int desiredListSize = 5;
final ArrayList<String> textWords = new ArrayList<String>();
textWords.add("key1 key2 key3 key4 key5 key6 key7");
textWords.add("key11 key12 key13 key14 key15 key16 key17");
final List<List<String>> listOfLists = textWords.stream().flatMap(w -> {
final String[] wordList = StringX.splitStrIntoWordsRtrnArr(w); // w.split(" ");
int calculatedListSize = (wordList.length < desiredListSize) ? wordList.length : desiredListSize;
return IntStream.range(0, Math.min(wordList.length - (calculatedListSize - 1), wordList.length)).mapToObj(i -> i ).flatMap(i -> Stream.of(
IntStream.range(i, Math.min(i+desiredListSize, wordList.length)).mapToObj(j -> wordList[j])
.collect(Collectors.toList())));
}) .collect(Collectors.toList());
for (int counter = 0; counter < listOfLists.size(); counter++) {
System.out.println("LIST: " + counter);
System.out.println(listOfLists.get(counter).toString());
}
}
, который выдает следующий вывод:
LIST: 0
[key1, key2, key3, key4, key5]
LIST: 1
[key2, key3, key4, key5, key6]
LIST: 2
[key3, key4, key5, key6, key7]
LIST: 3
[key11, key12, key13, key14, key15]
LIST: 4
[key12, key13, key14, key15, key16]
LIST: 5
[key13, key14, key15, key16, key17]
Однако идеальный вывод:
LIST 0:
key1 key2 key3 key4 key5
key2 key3 key4 key5 key6
key3 key4 key5 key6 key7
LIST 1:
key11 key12 key13 key14 key15
key12 key13 key14 key15 key16
key13 key14 key15 key16 key17
Затем оба списка должны быть добавлены к listOfLists
.
Обратите внимание, что в желаемом выводе каждый список сохраняет результат операции со строкой: key1 key2 key3 key4 key5
как один String
( с пробелом между каждым словом) НЕ как список .
Другими словами, когда кто-то вызывает listOfLists.get(0);
one s должен получить список, который содержит результаты операции на words.add("key1 key2 key3 key4 key5 key6 key7");
, а когда вы вызываете listOfLists.get(1);
, вы должны получить результаты операции на words.add("key11 key12 key13 key14 key15 key16 key17");
Конечно, если в исходном textWords
List больше двух записей, то listOfLists
будет содержать соответствующее количество списков.
Спасибо!