Java 拆分长行,缩进并输出
我有一个从字符串中删除重复单词的代码。假设我有:Java 拆分长行,缩进并输出,java,string,Java,String,我有一个从字符串中删除重复单词的代码。假设我有: 这是一项严肃的工作。我应用代码并得到:这是一项严肃的工作 代码如下: return Arrays.stream(input.split(" ")).distinct().collect(Collectors.joining(" ")); 现在,我想添加新的约束,即如果字符串/行长度超过78个字符,请在有意义的地方将其打断并缩进,以便行的长度不超过78个字符。例如: This one is a very long line that runs
这是一项严肃的工作
。我应用代码并得到:这是一项严肃的工作
代码如下:
return Arrays.stream(input.split(" ")).distinct().collect(Collectors.joining(" "));
现在,我想添加新的约束,即如果字符串/行长度超过78个字符,请在有意义的地方将其打断并缩进,以便行的长度不超过78个字符。例如:
This one is a very long line that runs off the right side because it is longer than 78 characters long
那就应该是
This one is a very long line that runs off the right side because it is longer
than 78 characters long
我找不到解决这个问题的办法。有人提请我注意,我的问题可能有重复之处。我在那里找不到我的答案。我需要能够缩进。您可以在
字符串的基础上创建一个StringBuilder
,然后在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 is a great sentence. It is a great example.
它将删除重复的is
、great
和a
,然后返回
This is a great sentence. It example.
要仅删除连续重复的单词,可以查看以下解决方案:
或者,您可以通过将文本拆分为单词,并将当前元素与其前面的元素进行比较来删除连续重复的单词,而不是使用
Collectors.joining(" ")
可以编写一个自定义收集器,在适当的位置添加新行和缩进
让我们介绍一个LineWrapper类,它包含缩进和限制字段:
public class LineWrapper {
private final int limit;
private final String indent;
默认构造函数将字段设置为合理的默认值。
请注意缩进是如何以新行字符开始的
public LineWrapper() {
limit = 78;
indent = "\n ";
}
自定义构造函数允许客户端指定限制和缩进:
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;
}
apply方法将输入拆分并将单词收集到指定最大长度的行中,缩进行并删除重复的连续单词。请注意,使用Stream.distinct方法不会删除重复项,因为它也会删除不连续的重复项
public String apply(String input) {
return Arrays.stream(input.split(SPACES)).collect(toWrappedString());
}
toWrappedString方法返回一个收集器,该收集器在新的ArrayList中累积单词,并使用以下方法:
- AddifyDistinct:将单词添加到ArrayList
- 合并:合并两个数组列表
- 换行:拆分和缩进行
收集器拖缆字符串(){
返回收集器.of(ArrayList::new,
此::addifydistinct,
这个……联合收割机,
这个(包装);
}
如果该单词与前一个单词不同,AddifyDistinct会将该单词添加到累加器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);
}
}
void addifydistinct(数组列表累加器,字符串字){
如果(!acculator.isEmpty()){
字符串lastWord=acculator.get(acculator.size()-1);
如果(!lastWord.equals(word)){
累加器。添加(word);
}
}否则{
累加器。添加(word);
}
}
combine方法将第二个ArrayList中的所有单词添加到第一个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;
}
ArrayList组合(ArrayList单词,
ArrayList moreWords){
列出其他=更多单词;
如果(!words.isEmpty()&&!other.isEmpty()){
字符串lastWord=words.get(words.size()-1);
if(lastWord.equals(other.get(0))){
other=other.subList(1,other.size());
}
}
文字:addAll(其他);
返回单词;
}
最后,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();
}
字符串换行(ArrayList单词){
StringBuilder结果=新建StringBuilder();
如果(!words.isEmpty()){
String firstWord=words.get(0);
结果。追加(第一个字);
int lineLength=firstWord.length();
for(字符串字:words.subList(1,words.size())){
//在单词长度上加1,
//说明空格字符
int len=word.length()+1;
如果(LeelStHeal+LeN)为什么不使用类似于:TXT?子串(0,77)+“\n”+txt?子串(78);?@ doLyON,可能会在一个单词的中间复制,非常感谢您的帮助。但是出于某种原因,您的解决方案似乎是切断了“IS”。原文string@Devee这是因为在您创建的流中,您只允许每个单词中的一个。如果您只想删除连续的重复单词,则必须更改流
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);
}
}
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;
}
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();
}