【问题标题】:Convert nested for loop logic to for each and java stream将嵌套的 for 循环逻辑转换为 for each 和 java 流
【发布时间】:2021-06-06 04:32:09
【问题描述】:

下面的代码将跳过索引 i=0,j=0 处的字符串,如果它再次出现在任何地方。如果最终数据列表为空或最终数据字符串的大小为 1000,它还将添加一个额外的标题。我希望为每个循环和 java 流语法编写相同的代码。有人可以帮帮我吗?

List<List<String>> completedata=new ArrayList<>(); // Suppose it contains many lists which have around 5000 strings in total
List<String> finaldata=new ArrayList<>();
String header="Heading";
String temp=null;
for(int i=0;i<completedata.size();i++) {
    for (int j = 0; j < completedata.get(i).size(); j++) {
                if ((i == 0 || j == 0) || completedata.get(i).get(j).equals(temp)) {
                    temp = completedata.get(i).get(j);
                    continue;
                }
                if (finaldata.size() == 0 || (finaldata.size() % 1000 == 0)) {
                    finaldata.add(header);
                }
                finaldata.add(completedata.get(i).get(j));
        }
}

【问题讨论】:

  • 如果这是为了家庭作业(在我看来很有可能),请参阅此常见问题解答meta.stackoverflow.com/questions/334822/…
  • 尤其是这个是相关的:真诚地尝试自己先解决问题。如果你的问题给他们的印象是你要求他们为你做你的工作,这里的用户会做出否定的反应。另一方面,询问您遇到的特定问题的问题通常会得到更好的答复。
  • 好吧,我无法继续,这就是我在这里寻求帮助的原因
  • 究竟是什么不适合你?
  • 对java流语法不太了解

标签: java for-loop java-stream


【解决方案1】:

这个任务的解决方案来自于定义。

  • 如果列表列表应转换为普通的List,则使用Stream::flatMap
  • 如果需要跳过索引为 0 的列表元素,则应使用Stream::skip(1)
  • 如果不需要重复元素,则应应用Stream::distinct
  • 如果需要将某些值添加到结果列表中,可以使用Collectors.collectingAndThenIntStream.range 来计算需要插入"Heading" 的索引。

总而言之,示例实现如下所示:

public static final List<String> formatData(List<List<String>> data, String header, int afterN) {
    return data.stream().skip(1) // skip i == 0
               .flatMap(lst -> lst.stream().skip(1)) // skip j == 0, make flat list
               .distinct() // remove duplicates
               .collect(Collectors.collectingAndThen(
                       Collectors.toList(),
                       lst -> IntStream.range(0, lst.size()).boxed()
                               .flatMap(i -> i % afterN == 0
                                       ? Stream.of(header, lst.get(i))
                                       : Stream.of(lst.get(i))
                               )
                               .collect(Collectors.toList())
               ));
}

测试

List<List<String>> data = Arrays.asList(
        Arrays.asList("Skipped line"),
        Arrays.asList("Skipped column 1", "column1", "column2", "column3"),
        Arrays.asList("Skipped column 2", "value 2.1", "value 2.2", "value 2.3"),
        Arrays.asList("Skipped column 3", "value 3.1", "value 3.2", "value 3.3"),
        Arrays.asList("Skipped column 4", "value 4.1", "value 4.2", "value 4.3"),
        Arrays.asList("Skipped column 5", "value 5.1", "value 5.2", "value 5.3", "value 5.3"),
        Arrays.asList("Skipped column 6", "6.1", "6.2", "6.3", "value 5.1", "value 4.2"),
        Arrays.asList("Skipped column 7", "7.1", "7.2", "7.3", "7.1", "7.3"),
        Arrays.asList("Skipped column 8", "8.1", "8.2", "8.3", "8.4", "8.4", "8.5")
);

// use \n to improve output, insert header after each 3 elements
List<String> finalData = formatData(data, "\nHeader", 3); 

System.out.println(finalData);

输出(没有重复元素)

[
Header, column1, column2, column3, 
Header, value 2.1, value 2.2, value 2.3, 
Header, value 3.1, value 3.2, value 3.3, 
Header, value 4.1, value 4.2, value 4.3, 
Header, value 5.1, value 5.2, value 5.3, 
Header, 6.1, 6.2, 6.3, 
Header, 7.1, 7.2, 7.3, 
Header, 8.1, 8.2, 8.3, 
Header, 8.4, 8.5]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 2017-03-16
    • 2019-04-05
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多