问题
I am attempting to split a String
(stored in ArrayList
) into fixed number of words (not characters) recursively.
For example, suppose I have the an ArrayList
which contains the following two String
phrases:
ArrayList<String> words = new ArrayList<String>();
words.add("key1 key2 key3 key4 key5 key6 key7");
words.add("key11 key12 key13 key14 key15 key16 key17");
And I want to split into chunks of 5 words (int desiredListSize = 5;
) - this would produce the following two lists:
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
Each list above would then be added to List of Lists array so the output would be in format: ArrayList<ArrayList<String>()
So far the following code fragment solves most of the problem:
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());
}
}
Which produces the following output:
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]
However the ideal output is:
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
Both lists above should then be added to listOfLists
.
Notice how in the desired output each list stores the result of operation on String: key1 key2 key3 key4 key5
as a single String
(with a space between each word) NOT as a list.
In other words, when one calls listOfLists.get(0);
one should obtain a list that contains the results of operation on words.add("key1 key2 key3 key4 key5 key6 key7");
and when one calls listOfLists.get(1);
one should obtain results of operation on words.add("key11 key12 key13 key14 key15 key16 key17");
Of course, if there's more than two entries in original textWords
List then listOfLists
will contain a corresponding number of lists.
Thanks!
回答1:
O.S. I don't have time right now to refine my posting, but here's the better (I think) of the original postings. I may get back tomorrow sometime, but I've got a job that needs doing too :-)
Anyway, here it is:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StackOverflow {
public static void main(final String[] args) {
final List<String> words = new ArrayList<>();
words.add("key1 key2 key3 key4 key5 key6 key7");
words.add("key11 key12 key13 key14 key15 key16 key17");
final List<List<String>> listOfLists = words.stream().flatMap(w -> {
final String[] wordList = w.split(" ");
return IntStream.range(0, Math.min( 3, wordList.length)).mapToObj(i -> i ).flatMap(i -> Stream.of(
IntStream.range(i, Math.min(i+5, wordList.length)).mapToObj(j -> wordList[j])
.collect(Collectors.toList())));
}) .collect(Collectors.toList());
listOfLists.forEach(System.out::println);
}
}
来源:https://stackoverflow.com/questions/60032231/split-string-into-fixed-number-of-words-recursively-java