2

I have an arrayList. And I need to return true if at least one item from my array isNumber. Here is my code:

    private boolean hasNumber(ArrayList<Item> items) {
          return Observable.fromIterable(items)
               .filter(Item::isNumber)                
                .toList()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(items-> items.size() > 0)
                .subscribe(result -> "");
   }

But I can't return true/false from this method. I don't understand how to return value with rxJava. Please help me.

  • 1
    @GhostCat he's prolly trying to learn. Nothing wrong with it. – Prashant Pandey Jul 21 '19 at 17:54
  • 1
    @PrashantPandey I disagree. You learn concepts by looking for *meaningful* applications. Doing something that is not meaningful, and can be done with 3 lines of old-school for-each looping, or a simple one-line stream() expression isn't too helpful. Also note that this community focuses on quality content, so even questions should be clear and somehow *rationale*, so that future readers can understand what they are about. This question asks how to open a can with a machine gun. You don't, you use a can opener. – GhostCat Jul 21 '19 at 18:00
  • I disagree. The user might be trying to do this using the push-pull model of Rx. How else would he implement a push-pull model using native Java? This question is at par with the standards of the community. Also, Rx has a pretty steep learning curve and I won't set out to create an entire application to experiment on something that can be done using a single main method. – Prashant Pandey Jul 21 '19 at 18:03
  • 1
    @GhostCat,This is just for example. In fact, I have a very large list of data. And I need to calculate a complex formula for each element and return true if at least one element after calculation of the formula has become zero. I need this calculation not to be made in the UI thread –  Jul 21 '19 at 18:09
  • That doesn't change much. You already **have** that list sitting there. To compute a value in a **blocking** method doesn't benefit **at all** from using Observable! – GhostCat Jul 21 '19 at 18:11
  • 1
    @ GhostCat, The calculation of the formula takes a few seconds. When I do this in a loop, the application freezes. –  Jul 21 '19 at 18:15
  • Yes, because you dont understand how to properly deal with the swing **event dispatcher thread**. The proper answer would be to use SwingUtilities.invokeLater() for example. Again: you are using the completely **wrong** tool to solve a very basic and common problem: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html – GhostCat Jul 21 '19 at 18:32
  • I don't understand why you're so contented on his choice of the Rx. Suppose the calculation is happening over a network and OP wants to do it in an NIO, async. way using say for example, Reactor Netty. Observable would be the perfect choice here. – Prashant Pandey Jul 21 '19 at 18:37
  • 1
    @ GhostCat, This is an android application, I don't need swing. I just need to perform the operation not in the UI thread, since it blocks it –  Jul 21 '19 at 18:47

2 Answers2

2

Try blockingFirst

private boolean hasNumber(ArrayList<Item> items) {
    return Observable.fromIterable(items)
        .filter(Item::isNumber)                
        .toList()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .map(items-> items.size() > 0)
        .blockingFirst();
}
Alan
  • 288
  • 4
  • 7
1

A hacky way to do this would be:

  private boolean hasNumber(List<Item> items) {
    Boolean[] res = new Boolean[1];
    res[0] = false;
    Observable.from(items).filter(this::isNumber).toList().subscribe(list -> {
        if(list.size() > 0) {
          res[0] = true;
        }
    });
    return res[0];
  }
Prashant Pandey
  • 4,332
  • 3
  • 26
  • 44
  • That might work (where I would use a boolean array, not Boolean), but I still dont see why doing so would make any sense. What is the purpose of using Observable ... when all the data is already in that list? Your answer maybe answers the question, but it doesn't add the "missing sense", imho. – GhostCat Jul 21 '19 at 17:54
  • Yeah does not make any sense, you're right. But he might be trying to learn. This example will teach him: 1. Why you can use only final or effectively final variables in Lambdas. 2. How did we overcome this in this example. – Prashant Pandey Jul 21 '19 at 17:56
  • Not really. If he would want to learn about lambdas and local variables, I would rather to existing questions here, that one over here https://stackoverflow.com/a/38402625/1531124 is a great introduction to that topic for example ;-) and never mind, your answer at least compiles ;-) x2 – GhostCat Jul 21 '19 at 18:09
  • @GhostCat totally. It's just that when I started out with this stuff, I used to ask a lot of such questions haha so I can totally relate to the OP. But your point stands absolutely. – Prashant Pandey Jul 21 '19 at 18:10