根据groupBy
的文件:
注意:
GroupedObservable
将缓存要发出的项目,直到订阅为止。因此,为了避免内存泄漏,您不应该忽略那些与您无关的GroupedObservable
。相反,您可以向他们发出信号,告知他们可以通过向take(int)(0)
这样的运算符应用来放弃缓冲区。
有一个RxJava tutorial,上面写着:
在内部,每个Rx操作员都做3件事
- 订阅源并观察值。
- 它根据操作者的目的转换观察到的序列。
- 通过调用onNext,onError和onCompleted,将修改后的序列推送给自己的订阅者。
醇>
让我们看看下面的代码块,它只从range(0, 10)
中提取偶数:
Observable.range(0, 10)
.groupBy(i -> i % 2)
.filter(g -> g.getKey() % 2 == 0)
.flatMap(g -> g)
.subscribe(System.out::println, Throwable::printStackTrace);
我的问题是:
这是否意味着filter
运营商已经暗示订阅了groupBy
或Observable<GroupedObservable>
仅产生的每个群组?
在这种情况下是否会出现内存泄漏?如果是这样,
如何正确丢弃这些群组?将filter
替换为自定义的take(0)
,其中return Observable.empty()
后跟take(0)
?您可能会问为什么我不能直接返回filter
:因为groupBy
在{{1}}之后不会立即跟进,但可以在任何地方链条涉及更复杂的条件。
答案 0 :(得分:5)
除了内存泄漏之外,由于内部请求协调问题,当前的实现可能会完全挂起。
请注意,使用take(0)
,可以始终重新创建组。我改为使用ignoreElements
来删除值,没有项目达到flatMap
,并且该组本身不会一直被重新创建。
答案 1 :(得分:4)
您的怀疑是正确的,为了正确处理分组的observable,必须订阅每个内部可观察量(import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Target {
/*--------------LINKED LIST------------------*/
private Node head;
private Node tail;
public void add(int obj) {
if (head == null) {
head = new Node(obj);
tail = head;
} else {
tail.next = new Node(obj);
tail = tail.next;
}
}
class Node {
public Node next;
public int item;
public Node(int item) {
this.item = item;
}
}
/*--------------LINKED LIST------------------*/
public Target() {
head = null;
}
public static void main(String args[]) throws FileNotFoundException {
Scanner fileIn = new Scanner(new File("in.txt"));
Target list = new Target();
while (fileIn.hasNext()) {
list.add(fileIn.nextInt()); //Read the file into the linkedlist.
}
fileIn.close();
System.out.println(list.recursiveSolution(list, 0));
}
public boolean recursiveSolution(Target list, int target) {
return subsetSumXOR(list.head, 0, 0, target);
}
private boolean subsetSumXOR(Node node, long sumOne, long sumTwo, int target) {
if (node == null) {
return (sumOne ^ sumTwo) == target; //base case, when node is null we've reached the end of the list.
}
return subsetSumXOR(node.next, sumOne + node.item, sumTwo, target) || subsetSumXOR(node.next, sumOne, sumTwo + node.item, target);
}
}
)。由于g
订阅了外部可观察量,所以只是一个坏主意。只需使用filter
在flatMap
中执行您需要的操作即可过滤掉不需要的群组。
ignoreElements