How to get element index when using a stream to traverse a list?

20,038

Solution 1

Here's how I would do it.

Run an IntStream over the indexes of the list. Then filter the indexes based on whether the corresponding checkbox is selected. Then map the index value, an int, into a String representation of index value. Finally, collect the strings into a result string, separated by commas.

Code:

    String result = IntStream.range(0, checkBoxes.size())
                             .filter(i -> checkBoxes.get(i).isSelected())
                             .mapToObj(String::valueOf)
                             .collect(Collectors.joining(","));

The output will be something like

    0,1,3,6

depending upon which checkboxes are actually checked.

I would avoid using forEach since you can accomplish the goal by transforming values instead of performing side effects. I would also avoid List.indexOf since that searches the list linearly for the desired item. It's not a big deal if you have only a few checkboxes, but if you have a lot, the O(N^2) growth will cause performance to suffer.

Solution 2

Try this, using IntStream:

List<CheckBox> checkBoxes = //data

IntStream.range(0, checkBoxes.size())
.forEach(i -> {
   CheckBox checkbox = checkBoxes.get(i); 
    if(checkbox.isSelected()){
        sb.append(i);
        sb.append(",");
    }
});

Solution 3

try

List<CheckBox> checkBoxes = null;
checkBoxes.forEach(checkBox -> {
    if(checkBox.isSelected()){
        index = checkBoxes.indexOf(checkBox);
        sb.append(index); //I want to get checkbox index here
        sb.append(",");
    }
});

Solution 4

lambda doesn't work for all cases, I would recommend using a traditional for loop.

for(int i = 0; i < checkBoxes.size(); i++){
    if(checkBoxes.get(i).isSelected()){
         // simply use "i" in this case for the index
         sb.append(i); //I want to get checkbox index here
         sb.append(",");
     }
}

However, if you insist on using streams you'll need to use the indexOf method provided by the List to get the corresponding index for that particular element.

checkBoxes.forEach(checkBox ->{
    if(checkBox.isSelected()){
          int indexValue = checkBoxes.indexOf(checkBox);
          sb.append(indexValue); //I want to get checkbox index here
          sb.append(",");
    }
});
Share:
20,038
Cyrus
Author by

Cyrus

Advanced Android engineer from China with 7 years in developing Android software. Proficient in using Java, Kotlin and most of design patter. Familiar with MVM,MVVP and have abundant experience in architecture design. Skilled use of various Unit Test Tools to write robust, extendable, reuseable code. 1 year experience as a team leader.

Updated on July 09, 2022

Comments

  • Cyrus
    Cyrus almost 2 years

    I want to get index when traverse list use lambda.

    For example:

    List<CheckBox> checkBoxes = null;
    
    checkBoxes.forEach(checkBox -> {
          if (checkBox.isSelected()) {
              sb.append("index"); //I want to get checkbox index here
              sb.append(",");
          }
    });
    

    EDIT: The checkBoxes = null; is just a placeholder but will be used properly once I start writing some code.

  • Cyrus
    Cyrus about 7 years
    Your answer has great value to me , but what makes me headache is it requires API 24.
  • Santanu Sahoo
    Santanu Sahoo over 6 years
    Please keep your lambda short and like one liner maybe