使用 java 8 将一段时间更改为 IntStream

Posted

技术标签:

【中文标题】使用 java 8 将一段时间更改为 IntStream【英文标题】:Changing a while to IntStream using java 8 【发布时间】:2021-08-05 18:17:01 【问题描述】:

我正在使用 Java 8,我试图将下面的代码转换为之前有 for 和 while 循环的代码,但不幸的是我无法将 while 转换为 IntStream。

有人可以帮我解决这个问题吗?另外,如果有人可以提出更好,更有效的方法。谢谢!

import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

public class NestedStreams 

    public static void main(String[] args) 

        ArrayList<String> a1 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "01", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a2 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "02", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a3 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "03", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a4 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "04", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a5 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "05", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a6 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "06", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a7 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "06", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a8 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "06", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a9 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "06", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a10 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "06", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a11 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "06", "90", null, "77", "00001", "AB").collect(Collectors.toList());
        ArrayList<String> a12 = (ArrayList<String>) Stream.of("ABC", "CFR", "DDR", "01", "M", null, "001", null, "00",
                null, "00", null, "00", "06", "90", null, "77", "00001", "AB").collect(Collectors.toList());

        ArrayList<ArrayList<String>> someList = new ArrayList<ArrayList<String>>();
        someList.addAll(Arrays.asList(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12));

        NestedStreams ns = new NestedStreams();
        String status = ns.testMethod(someList);
        if (status.equalsIgnoreCase("working")) 
            System.out.println("we can now do the processing");
         else 
            System.out.println("failure");
        

    

    public String testMethod(ArrayList<ArrayList<String>> someList) 
        try 
            IntStream.range(0, someList.size()).forEach(i -> 
                ArrayList<String> someOtherValues = (ArrayList<String>) someList.get(i);
                someOtherValues.replaceAll(t -> Objects.isNull(t) ? "" : t);
                AtomicInteger count = new AtomicInteger(4);
                AtomicInteger counter = new AtomicInteger(5);
                if (!someOtherValues.get(0).toString().equals("")) 
                    // while (count.intValue() < (someOtherValues.size()))  //Line 62
                    IntStream.range(count.intValue(), someOtherValues.size()).forEach(value ->  //Line 63
                        IntStream.range(0, 3).forEach(k -> 
                            String avalue = someOtherValues.get(count.intValue()).toString();//count is getting increased more than the length of arrayList //Line 65
                            System.out.println(avalue);
                            counter.incrementAndGet();
                        );
                        count.set(counter.intValue());
                        counter.incrementAndGet();
                        System.out.println("The variable value :-" + value);
                        System.out.println("The variable counter :-" + counter);
                        System.out.println("The variable count :-" + count);
                    );
                
            );
            return "working";
         catch (Exception e) 
            e.printStackTrace();
            return "failed";
        
    

代码的唯一问题是在更改为 IntStream 后,我无法检查条件 count

注意:上面的代码导致 java.lang.IndexOutOfBoundsException: Index: 20, Size: 19 您可以在第 62 行取消注释 while 循环并在第 63 行注释 IntStream 以获得完整的工作代码。

【问题讨论】:

在while循环中你使用someOtherValues.size(),但在第63行你使用someList.size()。为什么? 这是一个错字@Alex。我真的打算包括我在每次迭代 i 变量后得到的那些列表。感谢您指出这一点 修好了之后还能用吗? 不,这不是修复,这就是它的意思,我实际上打错了,当我在 Eclipse 上检查我的代码时,它是 someOtherValues.size()。当前编辑的代码会出错。 【参考方案1】:

IntStream 只返回一个顺序和有序的流。您不能期望它像 while 循环那样对每次迭代进行条目检查。如果您想获得 while 循环提供的相同结果,请包含 if 语句来检查条件。我在我的机器上运行了它,它提供了相同的结果。

      IntStream.range(count.intValue(), someOtherValues.size()).forEach(value ->  //Line 63

         // If condition here acts as the condition statement in a loop 
         if(count.intValue() < someOtherValues.size()) 
                  IntStream.range(0, 3).forEach(k -> 
                            
                   String avalue = someOtherValues.get(count.intValue()).toString();//count is getting increased more than the length of arrayList //Line 65
                   System.out.println(avalue);
                   counter.incrementAndGet();
                        );
                        count.set(counter.intValue());
                        counter.incrementAndGet();
                        System.out.println("The variable value :-" + value);
                        System.out.println("The variable counter :-" + counter);
                        System.out.println("The variable count :-" + count);
                     
            );

需要注意的几点:

    目前尚不清楚通过将while 更改为IntStream 来达到什么目的。但是,我将把它留给用例依赖项。由于您要求更好的方法,我建议坚持使用 while 循环,因为它以更简单的方式完成工作。 IntStream.range(start, end) 提供包含开头和结尾的值 我进行了更改,只是为了与 while 循环生成的输出相匹配。同样,由于您没有在此处提及您的目标,因此您应该注意正确性或预期输出。

干杯!

【讨论】:

IntStream.range(start, end) Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) 请在回答中修复 感谢@ram 的回答。我将while 转换为IntStream 的主要目的只是检查是否可以使用java 8 功能编写整个代码。如果您能看到之前使用的所有IntStream 是一个简单的for 循环。在循环中添加 if 只是为了检查条件没有多大意义,最好坚持使用while,正如您在第 1 点指出的那样。此外,我必须进行性能检查以检查这是否更有效或传统方式。

以上是关于使用 java 8 将一段时间更改为 IntStream的主要内容,如果未能解决你的问题,请参考以下文章

使用连接池一段时间后自动提交更改为 TRUE

我如何将我的 JRE 从 1.8.0.241 更改为最新的 13 [重复]

如何更优雅的使用 Java 8 函数式编程?

Java实现将一段汉字变成unicode码

使用条件将列更改为单独的数据框

Spring Boot 版本从 1.5.8 更改为 2.0.0