如何使用java Streams API在多个计数动态变化的情况下转换for循环n次以实现列表

如何使用java Streams API在多个计数动态变化的情况下转换for循环n次以实现列表,java,java-8,java-stream,Java,Java 8,Java Stream,要使用Streams API并删除下面代码段中的当前for循环: public List<MyObject> performSomeAction(){ List<String> myList= Arrays.asList("abc","xyz","def"); List<MyObject> resultList=new ArrayList<MyObject>(); int startIndex=0; int tota

要使用Streams API并删除下面代码段中的当前for循环:

public List<MyObject> performSomeAction(){
    List<String> myList= Arrays.asList("abc","xyz","def");
    List<MyObject> resultList=new ArrayList<MyObject>();
    int startIndex=0;
    int totalNumOfRecords=1000; 
    for(int i=0;i<totalNumOfRecords;i++){
        SomeObject o= xService.doSomething();
        String type = o.getType();
        int length = o.getLength();
        if(myList.contains(type)){
            int[] myarray=getMyArray(startIndex+20, startIndex+length);
            String id=o.getSomeId();
            OtherObject obj= xService.performOperation(myarray,"abcd");
            resultList.add(new MyObject(obj,id));
        }
        startIndex+=length;
    }
    return resultList;
}
但我陷入了困境,无法进一步了解如何继续,需要从派生对象“o”中获取多个值,并使用它在其上执行筛选,然后再次进行另一个方法调用获取一些数组,该数组将传递给其他方法以返回创建结果列表所需的其他对象

startIndex+=length;
意味着下一次迭代的行为取决于当前迭代后的状态

这基本上意味着迭代必须连续进行。因此,在这里堵住溪流没有任何好处

只需使用现有代码即可


我已经看到了OP询问如何重写代码以使用流的许多问题。隐式假设是流优于循环,因此流应该总是优先于循环使用

事实并非如此

与循环相比,流是:

  • 更严格的限制:不能使用流控制,如
    中断
    继续
    ;从周围环境中重新分配局部变量;抛出已检查的异常;从包含方法返回;在某些基本类型上循环
  • 更重量级:在构建流时创建了许多对象
  • 结构化程度较低:IMO称,使用平面映射的流比嵌套循环更难读取
  • 不太容易理解:我的经验是,许多人看到代码中的流,并认为它们很难理解,而且有点神奇。这将随着时间的推移而改变,因为他们对仍然相对较新的API更加熟悉;但在某种程度上,它们是正确的:streams API是大型的、特定于Java的,并且提供了许多方法来攻击自己。另一方面,(基本)循环实际上与所有类似C语言中的语法相同:一旦在其中一种语言中学习了它,您就可以立即“了解”循环在Java中的作用。对循环的增强甚至与C++、Python等
  • 基本相同。
但是,流可以是:

  • 更简洁:有时可以将“循环体”表示为lambda或方法引用,可以更短
  • 简单地并行化:虽然有效的Java3rded有一条关于为什么要非常小心地使用这个特性的条款
Streams是一种工具,其优点有限,缺点众多。重写现有的工作代码以使用它们确实不是一个好主意。

这一行:

startIndex+=length;
意味着下一次迭代的行为取决于当前迭代后的状态

这基本上意味着迭代必须连续进行。因此,在这里堵住溪流没有任何好处

只需使用现有代码即可


我已经看到了OP询问如何重写代码以使用流的许多问题。隐式假设是流优于循环,因此流应该总是优先于循环使用

事实并非如此

与循环相比,流是:

  • 更严格的限制:不能使用流控制,如
    中断
    继续
    ;从周围环境中重新分配局部变量;抛出已检查的异常;从包含方法返回;在某些基本类型上循环
  • 更重量级:在构建流时创建了许多对象
  • 结构化程度较低:IMO称,使用平面映射的流比嵌套循环更难读取
  • 不太容易理解:我的经验是,许多人看到代码中的流,并认为它们很难理解,而且有点神奇。这将随着时间的推移而改变,因为他们对仍然相对较新的API更加熟悉;但在某种程度上,它们是正确的:streams API是大型的、特定于Java的,并且提供了许多方法来攻击自己。另一方面,(基本)循环实际上与所有类似C语言中的语法相同:一旦在其中一种语言中学习了它,您就可以立即“了解”循环在Java中的作用。对循环的增强甚至与C++、Python等
  • 基本相同。
但是,流可以是:

  • 更简洁:有时可以将“循环体”表示为lambda或方法引用,可以更短
  • 简单地并行化:虽然有效的Java3rded有一条关于为什么要非常小心地使用这个特性的条款
Streams是一种工具,其优点有限,缺点众多。重写现有的工作代码以使用它们确实不是一个好主意

把它放在这里,这里有一个关于如何做的例子


您可以使用一个自定义的中间类来简化:

public List<MyObject> performSomeAction(){
    List<String> myList = Arrays.asList("abc","xyz","def");

    class ReductionHelper {
         int startIndex;
         final List<MyObject> resultList = new LinkedList<>();
    }

    return Stream.generate(xService::doSomething)
        .limit(1000)
        .reduce(new ReductionHelper(), (helper, o) -> {
            int length = o.getLength();
            if(myList.contains(o.getType()){
                int[] myarray=getMyArray(helper.startIndex+20, helperstartIndex+length);
                String id=o.getSomeId();
                OtherObject obj= xService.performOperation(myarray,"abcd");
                helper.resultList.add(new MyObject(obj,id));
            }
            helper.startIndex += length;
            return helper;
        }, (left, right) -> {
            left.resultList.addAll(right.resultList);
            return left;
        })
        .resultList; // return just the result list
}
public List performSomeAction(){
List myList=Arrays.asList(“abc”、“xyz”、“def”);
类简化助手{
国际标准指数;
最终列表结果列表=新建LinkedList();
}
返回Stream.generate(xService::doSomething)
.限额(1000)
.reduce(新ReductionHelper(),(helper,o)->{
int length=o.getLength();
if(myList.contains(o.getType()){
int[]myarray=getMyArray(helper.startIndex+20,helperstartIndex+length);
String id=o.getSomeId();
otherobjectobj=xService.performOperation(myarray,“abcd”);
add(新的MyObject(obj,id));
}
helper.startIndex+=长度;
返回助手;
},(左,右)->{
left.resultList.addAll(right.resultList);
左转;
})
.resultList;//仅返回结果列表
}
这只是使用类
ReductionHelper
来保存resultList和startIndex,但它非常混乱

正如您所看到的,这绝不会比您的c更具可读性