3

Can somebody let me know how to exit from forEach loop if some condition matches.I am using parallel stream.

Below is my code.

Map<int[], String[]> indexAndColNamePairs = depMapEntry.getKey();
Set<List<String>> dataRecords = depMapEntry.getValue();

for(Map.Entry<int[], String[]> indexAndColNamePair: indexAndColNamePairs.entrySet())
{
    int refColIndex = indexAndColNamePair.getKey()[0];
    Stream<List<String>> dataRecs = dataRecords.parallelStream();
    dataRecs.forEach((row) -> {
        if(referencingValue.equals(row.get(refColIndex)))
        {
            requiredColValueAndName.put(row.get(indexAndColNamePair.getKey()[1]),
                indexAndColNamePair.getValue()[1]);
        }
}); 

if(referencingValue.equals(row.get(refColIndex))) then i am inserting value to map and then i need to exit.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
Satheesh
  • 163
  • 1
  • 3
  • 11
  • Adding `break;` command at the end of your if block should do the trick. – Calvin P. Jan 15 '16 at 05:37
  • I dont want to break from for loop i want to break from forEach.Also it is not possible to use break or continue in if block. – Satheesh Jan 15 '16 at 05:42
  • for each is still a for loop, just a different implementation of it. break should still work – Calvin P. Jan 15 '16 at 05:45
  • i tried but it is saying break cannot be used outside of a loop or a switch – Satheesh Jan 15 '16 at 05:47
  • I believe the only way to abort the execution of stream would be to throw an exception. Parallel threads (tasks) are likely cancelled, but that may not be instantaneous. – Andreas Jan 15 '16 at 05:54
  • 1
    @CalvinP. OP is asking for java 8 forEach on stream, not "for-each" loop introduced in java 5. – Mrinal Jan 15 '16 at 05:54
  • Ah I was looking at the wrong bit of code. Not familiar with `.forEach` operations, but perhaps the following link will lead you in the right direction. http://stackoverflow.com/questions/20746429/limit-a-stream-by-a-predicate – Calvin P. Jan 15 '16 at 05:58
  • This may be closer yet. One of the answers appears to suggest using `return;` to break. http://stackoverflow.com/questions/23996454/terminate-or-break-java-8-stream-loop – Calvin P. Jan 15 '16 at 06:01

4 Answers4

3

As I understand your requirement, you want to execute one statement (requiredColValueAndName.put) for only one item in the list. Usage of Stream.forEach is not relevant for this use case. Instead find the item for which you want execute the statement first and then execute.


Optional<List<String>> expectedRow = dataRecs.filter(row -> referencingValue.equals(row.get(refColIndex))).findFirst();
    
if(expectedRow.isPresent()) {
requiredColValueAndName.put(
    expectedRow.get().get(indexAndColNamePair.getKey()[1]),
    indexAndColNamePair.getValue()[1]);
    
}
howie
  • 2,587
  • 3
  • 27
  • 43
Mrinal
  • 1,846
  • 14
  • 17
3

You can't. From the documentation:

In almost all cases, terminal operations are eager, completing their traversal of the data source and processing of the pipeline before returning. Only the terminal operations iterator() and spliterator() are not; these are provided as an "escape hatch" to enable arbitrary client-controlled pipeline traversals in the event that the existing operations are not sufficient to the task.

What you want is either filter() and findFirst() or iterate().

ktbiz
  • 586
  • 4
  • 13
  • 2
    ... or a plain old for-each loop! Just because we have fancy new tools, doesn't mean we shouldn't use the old ones when they do what we want! – yshavit Jan 15 '16 at 07:02
  • Indeed. I am in full agreement with you; but that wasn't really the question. =) – ktbiz Jan 15 '16 at 07:12
  • Yup, I agree (and I did upvote your answer, fwiw). Just a friendly reminder to the OP that if they want `break` behavior, the easiest answer may be the one they've known fur years. :) – yshavit Jan 15 '16 at 07:17
2

Somewhat more functional variation of @MrinalKSamanta answer:

indexAndColNamePairs.forEach((indices, colNames) -> {
    int refColIndex = indices[0];
    dataRecords.parallelStream()
               .filter(row -> referencingValue.equals(row.get(refColIndex)))
               .findFirst()
               .ifPresent(row ->
                   requiredColValueAndName.put(row.get(indices[1]), colNames[1]));
});

Note that if you are not restricted to put exactly the first matching value (or you expect at most one matching value), you may have better performance if you replace .findFirst() with .findAny().

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
0
private String checkforlogin(List<String[]> ld, String iname, String ipass) {

    for (String[] u : ld) {
        Log.e("u[1]" ,u[1]);
        Log.e("u[2]" ,u[2]);

        if(u[1].toString().equals(iname) && u[2].toString().equals(ipass)){
            System.out.println("Bingo!!!" + u[0] + " " + u[1] + " " + u[2]);
            //go the the MainActivity
            retur_val = u[0];
        }else{
            if(retur_val.equals("-1"))
            {
                retur_val = "-1";
            }else {
                Log.e("already" , "got the value");
            }

// return retur_val;

        }
    }
    return retur_val;
}

//++++++++++++++++++++++++++++++++++++++++++++ retur_val is a calss variable which is "-1"