2 回答

TA貢獻1805條經驗 獲得超10個贊
您可以創(chuàng)建一個StringBuilderoff,String然后在 78 個字符后的最后一個分詞處插入換行符和制表符。您可以通過獲取前 78 個字符的子字符串,然后找到最后一個空格的索引來找到插入換行符/制表符的最后一個單詞:
StringBuilder sb = new StringBuilder(Arrays.stream(input.split(" ")).distinct().collect(Collectors.joining(" ")));
if(sb.length() > 78) {
int lastWordBreak = sb.substring(0, 78).lastIndexOf(" ");
sb.insert(lastWordBreak , "\n\t");
}
return sb.toString();
輸出:
This one is a very long line that runs off the right side because it longer
than 78 characters
你Stream也沒有做你想做的事。是的,它刪除了重復的單詞,但是.. 它刪除了重復的單詞。所以對于String:
This is a great sentence. It is a great example.
它將刪除重復的is,great和a, 并返回
This is a great sentence. It example.
要僅刪除連續(xù)重復的單詞,您可以查看以下解決方案:
使用正則表達式從文本中刪除連續(xù)重復的單詞并顯示新文本
或者,您可以通過將文本拆分為單詞來創(chuàng)建自己的元素,并將當前元素與其前面的元素進行比較以刪除連續(xù)的重復單詞

TA貢獻1797條經驗 獲得超4個贊
而不是使用
Collectors.joining(" ")
可以編寫一個自定義收集器,在適當?shù)奈恢锰砑有滦泻涂s進。
讓我們介紹一個 LineWrapper 類,它包含縮進和限制字段:
public class LineWrapper {
private final int limit;
private final String indent;
默認構造函數(shù)將字段設置為合理的默認值。請注意縮進如何以換行符開頭。
public LineWrapper() {
limit = 78;
indent = "\n ";
}
自定義構造函數(shù)允許客戶端指定限制和縮進:
public LineWrapper(int limit, String indent) {
if (limit <= 0) {
throw new IllegalArgumentException("limit");
}
if (indent == null || !indent.matches("\\n *")) {
throw new IllegalArgumentException("indent");
}
this.limit = limit;
this.indent = indent;
}
以下是用于將輸入拆分為一個或多個空格的正則表達式。這確保拆分不會產生空字符串:
private static final String SPACES = " +";
apply 方法拆分輸入并將單詞收集到指定最大長度的行中,縮進行并刪除重復的連續(xù)單詞。請注意如何使用 Stream.distinct 方法不刪除重復項,因為它還會刪除不連續(xù)的重復項。
public String apply(String input) {
return Arrays.stream(input.split(SPACES)).collect(toWrappedString());
}
toWrappedString 方法返回一個收集器,該收集器將單詞累積到一個新的 ArrayList 中,并使用以下方法:
addIfDistinct:將單詞添加到 ArrayList
combine:合并兩個數(shù)組列表
wrap:分割和縮進行
.
Collector<String, ArrayList<String>, String> toWrappedString() {
return Collector.of(ArrayList::new,
this::addIfDistinct,
this::combine,
this::wrap);
}
如果單詞與前一個單詞不同,則 addIfDistinct 將單詞添加到累加器 ArrayList 中。
void addIfDistinct(ArrayList<String> accumulator, String word) {
if (!accumulator.isEmpty()) {
String lastWord = accumulator.get(accumulator.size() - 1);
if (!lastWord.equals(word)) {
accumulator.add(word);
}
} else {
accumulator.add(word);
}
}
combine 方法將第二個 ArrayList 中的所有單詞添加到第一個。它還確保第二個 ArrayList 的第一個單詞不與第一個 ArrayList 的最后一個單詞重復。
ArrayList<String> combine(ArrayList<String> words,
ArrayList<String> moreWords) {
List<String> other = moreWords;
if (!words.isEmpty() && !other.isEmpty()) {
String lastWord = words.get(words.size() - 1);
if (lastWord.equals(other.get(0))) {
other = other.subList(1, other.size());
}
}
words.addAll(other);
return words;
}
最后,wrap 方法將所有單詞附加到 StringBuffer,當達到行長限制時插入縮進:
String wrap(ArrayList<String> words) {
StringBuilder result = new StringBuilder();
if (!words.isEmpty()) {
String firstWord = words.get(0);
result.append(firstWord);
int lineLength = firstWord.length();
for (String word : words.subList(1, words.size())) {
//add 1 to the word length,
//to account for the space character
int len = word.length() + 1;
if (lineLength + len <= limit) {
result.append(' ');
result.append(word);
lineLength += len;
} else {
result.append(indent);
result.append(word);
//subtract 1 from the indent length,
//because the new line does not count
lineLength = indent.length() - 1 + word.length();
}
}
}
return result.toString();
}
添加回答
舉報