, .
materialize, scan flatMap. scan partitionId , . materialize , , , , . flatMap , ( partitionId) (), .
unit test, 1, 1, 2, 2, 2, 3 {1, 1}, {2, 2, 2}, {3}.
.
:
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
import rx.Observable;
public class StateMachineExampleTest {
@Test
public void testForStackOverflow() {
Observable<Integer> a = Observable.just(1, 1, 2, 2, 2, 3);
State<Integer> initial = new State<Integer>(Collections.emptyList(), Optional.empty(),
false);
List<List<Integer>> lists = a.materialize()
.scan(initial,
(state, notification) -> {
if (notification.isOnCompleted()) {
return new State<>(null, state.value, true);
} else if (notification.isOnError())
throw new RuntimeException(notification.getThrowable());
else if (state.list.size() == 0) {
return new State<>(Arrays.asList(notification.getValue()), Optional
.empty(), false);
} else if (partitionId(notification.getValue()) == partitionId(state.list
.get(0))) {
List<Integer> list = new ArrayList<>();
list.addAll(state.list);
list.add(notification.getValue());
return new State<>(list, Optional.empty(), false);
} else if (state.value.isPresent()) {
if (partitionId(state.value.get()) == partitionId(notification
.getValue())) {
return new State<>(Arrays.asList(state.value.get(),
notification.getValue()), Optional.empty(), false);
} else {
return new State<>(Arrays.asList(state.value.get()), Optional
.of(notification.getValue()), false);
}
} else {
return new State<>(state.list,
Optional.of(notification.getValue()), false);
}
})
.flatMap(state -> {
if (state.completed) {
if (state.value.isPresent())
return Observable.just(Arrays.asList(state.value.get()));
else
return Observable.empty();
} else if (state.value.isPresent()) {
return Observable.just(state.list);
} else {
return Observable.empty();
}
})
.toList().toBlocking().single();
assertEquals(Arrays.asList(Arrays.asList(1, 1), Arrays.asList(2, 2, 2), Arrays.asList(3)),
lists);
}
private static int partitionId(Integer n) {
return n;
}
private static final class State<T> {
final List<T> list;
final Optional<T> value;
final boolean completed;
State(List<T> list, Optional<T> value, boolean completed) {
this.list = list;
this.value = value;
this.completed = completed;
}
}
}
, . .
, , , materialize, scan flatMap, , , zip.