如何在rx java中分组并返回列表

时间:2017-09-19 03:05:33

标签: android rx-java rx-android

我试图根据Rxjava中的某些条件创建组列表。

以下是我的回复:

{  
   "dates":[  
      {  
         "date":18,
         "value":"1"
      },
      {  
         "date":18,
         "value":"2"
      },
      {  
         "date":18,
         "value":"3"
      },
      {  
         "date":19,
         "value":"1"
      },
      {  
         "date":19,
         "value":"2"
      },
      {  
         "date":19,
         "value":"3"
      },
      {  
         "date":19,
         "value":"4"
      }
   ]
}

如何按值18 [值1,值2,值3,最高值= 3,最低值= 1]进行分组 19 [值1,值2,值3,值4,最高值= 4,最低值= 1]使用Rxjava

注意:我可以使用for循环创建,但响应将从服务器获取,因为它返回了使用rx java功能的可观察的想法。

Anyhelp将非常感激。

谢谢你, Shanthi

5 个答案:

答案 0 :(得分:5)

了解group by功能。

以下是任何好奇的人的例子:

class DateModel implements Comparable<DateModel>{
    Integer date;
    Integer value;

    public DateModel(int date, int value){
        this.date = date; 
        this.value = value;
    }

    @Override
    public int compareTo(DateModel o) {
        return value.compareTo(o.value);
    }
}

然后,如果我们必须聚合这些模型对象的列表:

// example list
List<DateModel> dateList = Arrays.asList(
  new DateModel(18,1),
  new DateModel(18,2),
  new DateModel(18,3),
  new DateModel(19,1),
  new DateModel(19,2),
  new DateModel(19,3),
  new DateModel(19,4)
);

// the following observable will give you an emission for every grouping
// for the example data above, you should get two emissions (group 18 and 19)
Observable<PriorityQueue<DateModel>> observable = 
  Observable.from(dateList)
    .groupBy(dateModel -> dateModel.date)
    .flatMap(groups -> groups.collect(PriorityQueue::new, PriorityQueue::add));

PriorityQueue只是用于收集的结构的一个例子。如果你从队列中弹出,你会得到18-1,18-2,18-3等(按你要求的顺序)。您可以使用不同的结构,仅用于查找最大值和最大值。分钟。

答案 1 :(得分:2)

受到@Jon的回答的启发。这是Rxjava2和输出的完整演示代码。

    {li> Observable#collect() Observable {li> Flowable#parallel() + Single#blockingGet() Flowable

输出:

----------------------byCollect
[2017/11/16 20:42:43.548 CST][   1 -                           main] - flatMapSingle :  : 1
[2017/11/16 20:42:43.590 CST][   1 -                           main] - flatMapSingle :  : 2
[2017/11/16 20:42:43.591 CST][   1 -                           main] - flatMapSingle :  : 0
[2017/11/16 20:42:43.592 CST][   1 -                           main] - subscribe : onNext : {0=[3, 6, 9]}
[2017/11/16 20:42:43.593 CST][   1 -                           main] - subscribe : onNext : {1=[1, 4, 7]}
[2017/11/16 20:42:43.593 CST][   1 -                           main] - subscribe : onNext : {2=[2, 5, 8]}
[2017/11/16 20:42:43.597 CST][   1 -                           main] - subscribe : onComplete : 
----------------------byParallelAndBlockingGet
[2017/11/16 20:42:43.629 CST][  13 -      RxComputationThreadPool-1] - flatMap :  : 1
[2017/11/16 20:42:43.629 CST][  15 -      RxComputationThreadPool-3] - flatMap :  : 0
[2017/11/16 20:42:43.629 CST][  14 -      RxComputationThreadPool-2] - flatMap :  : 2
[2017/11/16 20:42:43.632 CST][  15 -      RxComputationThreadPool-3] - subscribe : onNext : {0=[3, 6, 9]}
[2017/11/16 20:42:43.632 CST][  15 -      RxComputationThreadPool-3] - subscribe : onNext : {1=[1, 4, 7]}
[2017/11/16 20:42:43.633 CST][  15 -      RxComputationThreadPool-3] - subscribe : onNext : {2=[2, 5, 8]}
[2017/11/16 20:42:43.633 CST][  15 -      RxComputationThreadPool-3] - subscribe : onComplete : 

来源:Demo.java

import io.reactivex.*;
import io.reactivex.Observable;
import io.reactivex.schedulers.*;

import java.time.*;
import java.time.format.*;
import java.util.*;

/**
 *   List<Integer>              // [1..9]
 *   ->
 *   Map<Integer,List<Integer> //  {0: [3,6,9],  1: [1,4,7],  2: [2,5,8] }
 */
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        byCollect();
        byParallelAndBlockingGet();
    }

    public static void byCollect() throws InterruptedException {
        System.out.println("----------------------byCollect");
        Observable.range(1, 9)
                .groupBy(i -> i % 3)
                .flatMapSingle(f -> {  // GroupedObservable<Integer, List<Integer>>

                    // Look output : all runs on same thread,
                    print("flatMapSingle : ", f.getKey());

                    // "onComplete" has not been triggered.
                    // blockingGet will block current thread.
                    //return Observable.just(Collections.singletonMap(f.getKey(), f.toList().blockingGet()))

                    return f.collect(
                            // (Callable<Map<Integer, List<Integer>>>)
                            () -> Collections.singletonMap(f.getKey(), new ArrayList<Integer>()),

                            // (BiConsumer<Map<Integer, List<Integer>>, Integer>)
                            (m, i) -> m.get(f.getKey()).add(i)
                    );

                })
                .subscribe(
                        i -> print("subscribe : onNext", i),
                        err -> print("subscribe : onError", err),
                        () -> print("subscribe : onComplete", "")
                )
        ;
    }

    public static void byParallelAndBlockingGet() throws InterruptedException {
        System.out.println("----------------------byParallelAndBlockingGet");
        Flowable.range(1, 9)
                .groupBy(i -> i % 3)
                .parallel()  // There's no `parallel` method on `Observable` class
                .runOn(Schedulers.computation())  // Important!!!
                .flatMap(f -> { // ParallelFlowable<GroupedFlowable<Integer, List<Integer>>
                    // Look output : runs on different thread each.
                    print("flatMap : ", f.getKey());
                    return Flowable.just(Collections.singletonMap(f.getKey(), f.toList().blockingGet()));
                })
                .sequential()
                .subscribe(
                        i -> print("subscribe : onNext", i),
                        err -> print("subscribe : onError", err),
                        () -> print("subscribe : onComplete", "")
                )
        ;
        Thread.sleep(500);
    }

    public static void print(String step, Object data) {
        ZonedDateTime zdt = ZonedDateTime.now();
        String now = zdt.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS z"));
        System.out.printf("[%s][%4d - %30s] - %10s : %s%n",
                now,
                Thread.currentThread().getId(),
                Thread.currentThread().getName(),
                step,
                data
        );
    }
}

答案 2 :(得分:1)

这是我的解决方案,在firebase.auth().onAuthStateChanged(function(user) { if (user) { // User is signed in. var displayName = user.displayName; var email = user.email; var emailVerified = user.emailVerified; var photoURL = user.photoURL; var isAnonymous = user.isAnonymous; var uid = user.uid; var providerData = user.providerData; // ... } else { // User is signed out. // ... } }); 通话中,您正在组成每个小组

.subscribe()

答案 3 :(得分:0)

这可以很容易地检索如下:

List<Date> list = Arrays.asList(new Date[]{
            new Date(18, 1), new Date(18, 2), new Date(18, 3), new Date(19, 1), new Date(19, 2)
    });

    Observable
            .fromArray(list)
            .map(new Function<List<Date>, List<Date>>() {
                @Override
                public List<Date> apply(@NonNull List<Date> dates) throws Exception {
                    TreeMap<Integer, List<Date>> treeMap = new TreeMap<Integer, List<Date>>();
                    for (Date date : dates) {
                        List<Date> storedDates = treeMap.get(date.date);
                        if (storedDates == null) {
                            storedDates = new ArrayList<Date>();
                            treeMap.put(date.date, storedDates);
                        }
                        storedDates.add(date);
                    }

                    List<Date> result = new ArrayList<Date>();
                    for (Integer integer : treeMap.keySet()) {
                        result.addAll(treeMap.get(integer));
                    }
                    return result;
                }
            });

答案 4 :(得分:-1)

感谢您的回复。

但是我能够使用以下代码解决它。

Map<String, List<Date>> grouped = dates.body().getDate()
                        .stream()
                        .collect(Collectors.groupingBy(x -> {
                            return x.getTime().getMday(); // we can use any logic here
                        }));