首页 > 解决方案 > Get indices of unique WebElements.getText() objects in an ArrayList

问题描述

I have an ArrayList<WebElements> whose elements all have some pieces of text. I'd like to store the indices of those WebElements, which contain unique pieces of text in a new ArrayList<Integer>. E.g. if the texts are (a,b,c,a,b,d) then I'd need (1,2,3,6).

I tried getting the texts to ArrayList<String> piecesOfText with one stream, picking the uniques with another one into ArrayList<String> piecesOfTextUnique, then looping through piecesOfTextUniqueand getting the indices of those pieces of text in piecesOfText via indexOf()

ArrayList<WebElement> webElementsWithText=getWebElements();
ArrayList<String> piecesOfText= new ArrayList<>();
webElementsWithText.stream()
    .map(WebElement::getText)
    .forEach(piecesOfText::add);
ArrayList<String> piecesOfTextUnique = (ArrayList<String>) piecesOfText.stream()
    .distinct()
    .collect(Collectors.toList());
ArrayList<Integer> uniqueIndeces=new ArrayList<>();
for (int i=0;i< piecesOfTextUnique.size();i++) {
    uniqueIndeces.add(piecesOfText.indexOf(piecesOfTextUnique.get(i)));
}

This one does the job, but can someone suggest a more concise/elegant solution?

标签: javaarraylistjava-stream

解决方案


  1. 您可以使用collect方法而不是Collection#add-ing in forEach
  2. 你不能假设Collectors.toList回报java.util.ArrayList。它可能导致ClassCastException.
  3. piecesOfTextUnique(语义上)与 等价piecesOfText.distinct(),因此piecesOfText可以内联。
  4. 最后一个 for 循环可以替换为IntStream.

所以,最终结果是:

ArrayList<WebElement> webElementsWithText = getWebElements();
List<String> piecesOfTextUnique = webElementsWithText.stream()
    .map(WebElement::getText)
    .distinct()
    .collect(Collectors.toList());
ArrayList<Integer> uniqueIndeces = IntStream.range(0, piecesOfTextUnique.size())
    .mapToObj(i -> piecesOfTextUnique.get(i))
    .map(s -> piecesOfText.indexOf(s))
    .collect(Collectors.toCollection(ArrayList::new));

推荐阅读