Реактивные расширения для Java - PullRequest
11 голосов
/ 16 мая 2010

Есть ли эквивалент Reactive Extensions (.NET) для Java?

О Rx (Reactive Extensions)

Rx - это библиотека для составления асинхронных и основанных на событиях программ с использованием наблюдаемых коллекций.

Мне известны механизмы правил, такие как Drools от JBOSS, но есть ли другой способ, более близкий к подходу Microsoft .NET?

Ответы [ 5 ]

18 голосов
/ 17 января 2013

Согласно этому сообщению в блоге NetFlix , они перенесли Rx на Java. Похоже, он еще не доступен, но у них есть история выпуска таких внутренне разработанных инструментов, как открытый исходный код, поэтому я ожидаю, что он будет выпущен в конце концов.

11 голосов
/ 16 мая 2010

Я не знаю ни одного - и, честно говоря, это было бы трудно сделать таким аккуратным способом. Сторона заправки в порядке; Java прекрасно справляется с многопоточностью ... но на данный момент язык просто не поддерживает соответствующие функции.

Одна из изящных конструктивных особенностей LINQ заключается в том, что все основано на интерфейсах, а затем методы расширения используются для добавления дополнительной функциональности. Это позволяет свободно читать код - представьте, что вам нужно написать:

IObservable<int> = Observable.Select(
                       Observable.Where(
                           source, x => x.SomeCondition)
                       x => x.SomeProjection);

Ик. Метод расширения гораздо более изящен:

IObservable<int> = source.Where(x => x.SomeCondition)
                         .Select(x => x.SomeProjection);

Теперь версия Java могла бы основываться на абстрактном базовом классе, но это утратило бы некоторую элегантность.

Далее идут лямбда-выражения и преобразования групп методов - это действительно фундаментально для LINQ в целом; ближайший эквивалент в Java (анонимные внутренние классы) слишком уродлив, чтобы использовать его везде, где вы бы использовали лямбда-выражение в C #.

В принципе, Java-версия Rx была бы возможна, но она не была бы столь же элегантной, как версия C # - возможно, поэтому, насколько я знаю, этого не было сделано. Для Java могут существовать другие «асинхронно-управляемые» библиотеки, но они вряд ли будут такими же полными и аккуратными, как Rx.

Возможно , что изменения в Java 7 сделают это более осуществимым; насколько я знаю, методы расширения не вводятся, но абстрактная версия базового класса будет разумной, если синтаксис лямбды окажется в порядке ...

3 голосов
/ 07 февраля 2011

Если вам все еще интересно, я в последнее время работаю над библиотекой Java , которая также предлагает большинство операторов Rx на реактивной и интерактивной стороне.

Это определенно не так хорошо, как .NET. В Java нет методов расширения или типов функций, поэтому все должно вызываться через статический метод и внутренние классы. В .NET:

Observable.Range(0, 10).SelectMany(
    o => Observable.Range(0, o)
).Run(Console.WriteLine);

Моя библиотека:

Reactive.run(
    Reactive.selectMany(
        Reactive.range(0, 10), 
        new Func1<Observable<Integer>, Integer>() {
            public Observable<Integer> invoke(Integer param1) {
               return Reactive.range(0, param1);
        }
    }       
), Reactive.println());

Interactive.run(
    Interactive.selectMany(
        Interactive.range(0, 10), 
        new Func1<Iterable<Integer>, Integer>() {
            public Iterable<Integer> invoke(Integer param1) {
               return Interactive.range(0, param1);
        }
    }       
), Interactive.println());

Я использую типы Func0, Func1, Func2 для лямбд и тип Closeable для отмены регистрации. Как только Java получает граждан функции первого класса, эти типы FuncX могут быть просто заменены. Closeable может использоваться улучшением Java 7 "попробуй с ресурсами". Третье уродство связано со слабым выводом типа в разных местах.

2 голосов
/ 29 января 2015

RxJava (RX перенесен Netflix) доступен и стабилен здесь: https://github.com/ReactiveX/RxJava.

Он даже очень хорошо работает с лямбда-синтаксисом в Java 8! Вы можете делать такие вещи:

Observable
  .from(Arrays.asList(1, 2, 3, 4, 5))
  .filter(val -> val % 2 == 0)
  .map(val -> val * val)
  .scan(0, (prev, curr) -> prev + curr)
  .subscribe(System.out::println)

Довольно круто?

1 голос
/ 04 июня 2010

Вы можете подумать о переносе raix ( wiki ), написанного на ActionScript 3, на Java 7, когда он появится. Проект (мой собственный) является открытым исходным кодом и включает в себя модульные тесты «черного ящика» версии .NET для обеспечения совместимости.

Как и Java, AS3 не поддерживает ни методы расширения, ни лямбда-выражения, поэтому реализация может быть схожей. Сказав это, вы должны быть осторожны с условиями гонки, поскольку AVM не поддерживает потоки, поэтому в RxAs нет кода блокировки.

...