请考虑以下类:
public class Order {
private String id;
private List<Order> orders = new ArrayList<>();
@Override
public String toString() {
return this.id;
}
// getters & setters
}
注意:很重要的一点是,我不能修改这个类,因为我是从外部API中使用它的。
还要考虑以下订单层次结构:
Order o1 = new Order();
o1.setId("1");
Order o11 = new Order();
o11.setId("1.1");
Order o111 = new Order();
o111.setId("1.1.1");
List<Order> o11Children = new ArrayList<>(Arrays.asList(o111));
o11.setOrders(o11Children);
Order o12 = new Order();
o12.setId("1.2");
List<Order> o1Children = new ArrayList<>(Arrays.asList(o11, o12));
o1.setOrders(o1Children);
Order o2 = new Order();
o2.setId("2");
Order o21 = new Order();
o21.setId("2.1");
Order o22 = new Order();
o22.setId("2.2");
Order o23 = new Order();
o23.setId("2.3");
List<Order> o2Children = new ArrayList<>(Arrays.asList(o21, o22, o23));
o2.setOrders(o2Children);
List<Order> orders = new ArrayList<>(Arrays.asList(o1, o2));
1
1.1
1.1.1
1.2
2
2.1
2.2
2.3
[1, 1.1, 1.1.1, 1.2, 2, 2.1, 2.2, 2.3]
通过递归地使用flatmap()
(以及一个helper类),我已经设法做到了这一点,如下所示:
List<Order> flattened = orders.stream()
.flatMap(Helper::flatten)
.collect(Collectors.toList());
这是helper类:
public final class Helper {
private Helper() {
}
public static Stream<Order> flatten(Order order) {
return Stream.concat(
Stream.of(order),
order.getOrders().stream().flatMap(Helper::flatten)); // recursion here
}
}
以下一行:
System.out.println(flattened);
产生以下输出:
[1, 1.1, 1.1.1, 1.2, 2, 2.1, 2.2, 2.3]
到目前为止还不错。结果是绝对正确的。
但是,在阅读了这个问题之后,我对flatmap()
在递归方法中的用法有些担心。特别是,我想知道流是如何被扩展的(如果这是术语的话)。因此,我修改了helper
类,并使用peek(System.out::println)
检查以下内容:
public static final class Helper {
private Helper() {
}
public static Stream<Order> flatten(Order order) {
return Stream.concat(
Stream.of(order),
order.getOrders().stream().flatMap(Helper::flatten))
.peek(System.out::println);
}
}
结果是:
1
1.1
1.1
1.1.1
1.1.1
1.1.1
1.2
1.2
2
2.1
2.1
2.2
2.2
2.3
2.3
我不确定这是否是应该打印的输出。
嗯,我在一个泛型tree
类中使用了相同的模式,并没有产生错误的感觉。唯一的区别是,tree
类本身提供了children()
和allDescendes()
方法,这两个方法都返回了stream
,后者建立在前者的基础上。这与“我应该返回一个集合还是一个流?”和“命名返回流的java方法”有关。
从流
的角度来看,对于不同类型的子级的FlatMap
(即在遍历属性时)和对于相同类型的子级的FlatMap
没有区别。如果返回的流再次包含相同的元素也没有问题,因为流的元素之间没有关系。原则上,您可以使用FlatMap
作为Filter
操作,使用模式FlatMap(x->condition?stream.of(x):stream.empty())
。也可以使用它来复制像这个答案中的元素。
我得到了三个整数操作: A-将3添加到number B-将数字 C加倍-交换number 的最后两位数字我应该编写算法来检查我是否可以在n步中使用操作A、B、C制作k素数。最后,我必须打印我用来制作k素数的操作序列。让我们假设我们有函数: 当数字为素数时,函数ifprime返回true,否则返回false。 代码: 我的问题是,我不知道如何记住正确的路径,然后打印出来。
我有,我只想有一个。我尝试使用,但它不起作用,因为它无法将SortedSet的流扁平化。
问题内容: 我必须用Java编写幂方法。它接收两个整数,无论它们是正数还是负数都没有关系。它应该具有的复杂度。它还必须使用递归。我当前的代码有两个数字,但我不断输出的结果是零,我不知道为什么。 问题答案: 让我们从一些数学事实开始: 对于正n,aⁿ=a⨯a⨯…⨯an次 对于负数n,aⁿ=⅟a⁻ⁿ=⅟(a⨯a⨯…⨯a)。这意味着 a 不能为零。 对于n = 0,即使 a 为零或负,aⁿ= 1 。
我写了下面的代码来反转链表的前K个节点,它在反转链表的前K个节点时解决了一些问题,为什么递归在最后一次迭代中执行两次,现在它可以正常工作,但为什么它会导致链表中的循环当我尝试在“if”条件下使用变量“k”而不是“PresCouner”时,原因是什么?以及如何避免它?
我试图了解如何将各种递归函数转换为尾递归。我已经查看了许多将斐波那契和阶乘转换为尾递归的示例,并理解了这些示例,但很难跳到具有某种不同结构的问题。一个例子是: 如何将其转换为尾部递归实现? 我已经看过类似的问题,例如:将正常递归转换为尾部递归,但这些似乎并没有转化为这个问题。
问题内容: 有什么方法可以混合使用递归和语句吗?例如,无限数生成器(使用递归)将类似于: 我试过了: 和 但是他们都没有做我想要的事情,第一个在屈服后停止,第二个在屈服之后,然后是发电机,然后停了下来。 注意: 请知道,您可以使用while循环来做到这一点: 我只想知道这是否可以递归进行。 问题答案: 是的,您可以这样做: 但是,一旦达到最大递归深度,这将出错。 从Python 3.3开始,您将可