Want to use Streams API and remove current for loop in code snippet below :
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;
}
I tried something like this :
IntStream.range(0,totalNumOfRecords).forEach(i -> xService.doSomething());
but i am stuck and not getting how to proceed further, need to take multiple values from derived object 'o' and use it to perform filter on top of it and again make another method call get some array which will be passed to other method to return other object that i need to create my resultList
This line:
startIndex+=length;
Means that the behaviour of the next iteration depends upon the state after the current iteration.
That basically means that the iteration has to happen serially. As such, there is no benefit from crowbarring Streams in here.
Just stick with your existing code.
I have seen many questions where OP is asking how to rewrite code to use streams. The implicit assumption is that streams are superior to loops , and so streams should always be used in preference to a loop.
This is not true .
In comparison to a loop, a stream is:
break
, continue
; reassign local variables from the surrounding context; throw checked exceptions; return from the containing method; loop over certain primitive types. However, a stream can be:
Streams are a tool, with limited benefits and numerous drawbacks. Rewriting existing, working code to use them is really not a good idea.
Just putting it here, so there's an example on how to do it
You could use a custom intermediate class with reduction for this:
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
}
This just uses the class ReductionHelper
to hold the resultList and the startIndex. But it is highly messy
So as you can see, this is in no way more readable than your current solution. Just stick with normal for loops as pointed out by @Andy Turners answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.