Java列表流,获取所有元素还是只有一个?

时间:2018-05-24 16:57:19

标签: java recursion java-8

我有一个返回元素Arraylist的方法。 有时我需要整个列表,有时只是检查结果列表是否为空(只是bool)。

由于该方法执行一些繁重的任务来检查是否应该将某些内容添加到结果列表中,是否有办法实现 如果它将一个元素添加到列表中,则在方法中断?

我想使用相同的方法,但有时会在列表中添加一个元素时中断,有时让它完成所有工作(并添加其他所有内容)。

我可以传递一些布尔标志,指示当第一个元素添加事件时该方法是否应该中断, 但我想知道是否有一个更优雅的解决方案(有流或什么......)。

我添加了伪代码作为示例。这个方法是递归的,如果我在第一次迭代中添加一个元素,我想(可选)避免额外的递归调用:

List<String> getData(argument) {
  List<String> elements = new ArrayList<>;
  ... // do some heavy stuff that produces flag 'shouldAddElement'

  if (shouldAddElement) {
    elements.add('a');
  }

  if (someCondition) {
    elements.addAll(getData(argument));
  }

  return elements;
}

2 个答案:

答案 0 :(得分:4)

您可以将谓词shouldContinue(或甚至等效shouldStop)传递给方法,并根据您可以决定继续/停止的谓词的评估。

但是,将此参数添加到公共方法可能看起来不合适,因此您可以创建两个方法 - 一个在添加一个元素后停止,另一个继续(因为无论如何调用者需要决定是否在之后停止)一个元素或继续前进(如果你决定传递一个标志) - 所以,你可能有两种方法IMO)。

List<String> getOneElementData(argument) {
    return getDataInternal(argument, elements -> elements.size < 1);
}

//You can even extend the above to take the desired final list size as a parameter
// and have the predicate as elements -> elements.size < desiredSize

List<String> getData(argument) {
      return getDataInternal(argument, elements -> true); //Always keep going
}

private List<String> getDataInternal(argument, Predicate<List<String>> shouldContinue) {
  List<String> elements = new ArrayList<>;
  ... // do some heavy stuff that produces flag 'shouldAddElement'

  if (shouldAddElement) {
    elements.add('a');
  }

  if (someCondition && shouldContinue.test(elements)) {
    elements.addAll(getData(argument));
  }

  return elements;
}

答案 1 :(得分:0)

不是很优雅。但你可以使用列表可变的事实 看到这个简单的例子:

List<String> list = new ArrayList<>();
list.add("A");  list.add("B");  list.add("C");
manipulateList(list);
System.out.println(list);

其中manipulateList由:

定义
void manipulateList(List<String> list) {
    list.add("D");
}

操纵后的打印输出是:

  

[A,B,C,D]

请注意,您使用方法返回值。它返回void。这样你就可以得到被操纵的List而无需你的方法返回它 现在让manipulateList返回boolean,您可以根据需要使用它。类似的东西:

boolean manipulateList(List<String> list, boolean stopOnconditionMet) {

    while (...) {//represents the long process

        if(conditionMet && stopOnconditionMet ) {
            return true;
        }
    }

    return false
} 

您还可以添加便捷方法:

List<String> manipulateList(List<String> list) {
    manipulateList(list, false);
    return list;
}