question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Creating two streams using zip from singe stream (split)

See original GitHub issue

Having the following program:

package org.foo;

import java.util.Random;

import rx.Observable;
import rx.util.functions.Action1;
import rx.util.functions.Func1;
import rx.util.functions.Func2;

import com.opengamma.lambdava.tuple.Pair;    // [com.opengamma/lambdava "0.3"] from: "http://maven.opengamma.com/nexus/content/groups/public/" 

public class Rx {

  static class Position {
    Position(String security, int qty) {
      this.qty = qty;
      this.security = security;
    }

    public int qty;
    public String security;
  }

  static double getMarketValueForSecurity(String security) {
    Random r = new Random(System.currentTimeMillis());
    return r.nextDouble();
  }

  static double calcValue(double mktValue, Position position, Double coefficent) {
    return mktValue * coefficent;
  }

  static Position[] portfolio = new Position[] {new Position("AAPL", 10), new Position("OG", 999), new Position("AAPL", 1000), new Position("M$", 910), new Position("HSBC", 1910) };

  public static void main(String[] args) {
    compute(portfolio);
  }

  public static void compute(Position... names) {
    Observable<Position> positions = Observable.from(names);

    // only big positions
    Observable<Position> onlyBigPositions = positions.filter(new Func1<Position, Boolean>() {
      @Override
      public Boolean call(Position position) {
        return position.qty > 100;
      }
    });

    Observable<Double> marketValuesForPositions = onlyBigPositions.map(new Func1<Position, Double>() {
      @Override
      public Double call(Position position) {
        return getMarketValueForSecurity(position.security);
      }
    });

    Observable<Double> fairValueCoefficient = Observable.from(1.2).repeat();
    Observable<Double> skewedValueCoefficient = Observable.from(1.3).repeat();

    Observable<Pair<Position, Double>> positionsWithMarketValues = onlyBigPositions.cache().zip(marketValuesForPositions, new ToPair<Position, Double>()).cache();

    Observable<Pair<Position, Double>> positionsWithFairValues = positionsWithMarketValues.zip(fairValueCoefficient, new ToPair<Pair<Position, Double>, Double>()).map(
        new Func1<Pair<Pair<Position, Double>, Double>, Pair<Position, Double>>() {
          @Override
          public Pair<Position, Double> call(Pair<Pair<Position, Double>, Double> e) {
            Pair<Position, Double> positionsWithMarketValue = e.getFirst();
            Position position = positionsWithMarketValue.getFirst();
            Double marketValue = positionsWithMarketValue.getSecond();
            Double c = e.getSecond();
            return Pair.of(position, calcValue(marketValue, position, c));
          }
        });

    Observable<Pair<Position, Double>> positionsWithFairValuesSkewed = positionsWithMarketValues.zip(skewedValueCoefficient, new ToPair<Pair<Position, Double>, Double>()).map(
        new Func1<Pair<Pair<Position, Double>, Double>, Pair<Position, Double>>() {
          @Override
          public Pair<Position, Double> call(Pair<Pair<Position, Double>, Double> e) {
            Pair<Position, Double> positionsWithMarketValue = e.getFirst();
            Position position = positionsWithMarketValue.getFirst();
            Double marketValue = positionsWithMarketValue.getSecond();
            Double c = e.getSecond();
            return Pair.of(position, calcValue(marketValue, position, c));
          }
        });

    positionsWithMarketValues.subscribe(new Action1<Pair<Position, Double>>() {
      @Override
      public void call(Pair<Position, Double> o) {
        System.out.println("Market value for position:" + o.getFirst().security + " is: " + o.getSecond());
      }
    });

    positionsWithFairValues.subscribe(new Action1<Pair<Position, Double>>() {
      @Override
      public void call(Pair<Position, Double> o) {
        System.out.println("Fair value for position:" + o.getFirst().security + " is: " + o.getSecond());
      }
    });

    positionsWithFairValuesSkewed.subscribe(new Action1<Pair<Position, Double>>() {
      @Override
      public void call(Pair<Position, Double> o) {
        System.out.println("Skewed Fair value for position:" + o.getFirst().security + " is: " + o.getSecond());
      }
    });

  }

  static class ToPair<A, B> implements Func2<A, B, Pair<A, B>> {

    @Override
    public Pair<A, B> call(A t, B u) {
      return Pair.of(t, u);
    }
  }
}

Why I get output:

Market value for position:OG is: 0.7260218088269859
Market value for position:AAPL is: 0.7260218088269859
Market value for position:M$ is: 0.7260218088269859
Market value for position:HSBC is: 0.7260218088269859
Fair value for position:OG is: 0.871226170592383
Fair value for position:AAPL is: 0.871226170592383
Fair value for position:M$ is: 0.871226170592383
Fair value for position:HSBC is: 0.871226170592383

instead of

Market value for position:OG is: 0.7260218088269859
Market value for position:AAPL is: 0.7260218088269859
Market value for position:M$ is: 0.7260218088269859
Market value for position:HSBC is: 0.7260218088269859
Fair value for position:OG is: 0.871226170592383
Fair value for position:AAPL is: 0.871226170592383
Fair value for position:M$ is: 0.871226170592383
Fair value for position:HSBC is: 0.871226170592383
Skewed Fair value for position:OG is: 0.3744282129019022
Skewed Fair value for position:AAPL is: 0.3744282129019022
Skewed Fair value for position:M$ is: 0.3744282129019022
Skewed Fair value for position:HSBC is: 0.3744282129019022

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
akarnokdcommented, Jan 31, 2014

Hi. Could you try it without cache() calls? In addition, using Observable.from(1.2).repeat() is kind of dangerous as it will push out a large number of values, filling up the queue of the zip operator and may cause (swallowed) OutOfMemoryException. Instead, I sugest using the zip(Iterable) overload with Guava’s Iterables.cycle(T...) This will ensure that zip only pulls the constant when the observable part produces a value.

0reactions
benjchristensencommented, May 20, 2014

Closing out as this is quite old. Please reopen if needed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Zipping streams using JDK8 with lambda (java.util.stream ...
Should you be able to zip two streams that are of different size, for example? What would the resulting stream look like then?...
Read more >
How to Split a Stream into Multiple Streams - Baeldung
In this tutorial, we'll learn how to split a stream into multiple groups and process them independently. 2. Using Collectors.
Read more >
Wrapper: 1-in, Multi-out — IoTPY: Python + Streams
split encapsulators read a single input stream and produce multiple output streams. The split functions are the inverse of corresponding merge functions; ...
Read more >
ZStream | ZIO
ZStream#partition function splits the stream into tuple of streams based on the predicate. The first stream contains all element evaluated to true, and...
Read more >
API — Streamz 0.6.4 documentation - Read the Docs
Stream ¶ ; combine_latest (*upstreams, **kwargs). Combine multiple streams together to a stream of tuples ; delay (upstream, interval, **kwargs). Add a time...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found