2010-05-16 3 views
11

Есть ли какой-либо эквивалент Reactive Extensions (.NET) для Java?Реактивные расширения для Java

О Rx (Reactive Extensions)

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

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

ответ

11

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

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

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

Ick. Метод расширения гораздо более изящным:

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

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

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

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

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

+0

Хорошо, спасибо. Возможно, это более возможно в Java 7 с закрытием. –

+2

Теперь вы можете написать это в Java: IObservable = source.where (condition()). Select (selector()). ToArray(); См. Github.com/nicholas22/jpropel-light –

1

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

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

+0

@ richard-szalay, спасибо за указатель. –

3

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

Это определенно не так хорошо, как .NET. Java не имеет методов расширения или типов функций, поэтому все должно вызываться через статический метод и внутренние классы. In.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 для лямбды и закрывающегося типа для Дерегистрация. После того, как Java получит гражданскую функцию первого класса, эти типы FuncX можно просто заменить. Closeable может использоваться улучшением try-with-resources в Java 7. Третья уродство объясняется слабым умозаключением в разных местах.

+1

Статический импорт может значительно повысить удобочитаемость! – thSoft

18

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

+11

RxJava Netflix теперь доступен по адресу https://github.com/Netflix/RxJava –

1

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) 

Довольно охлаждаться?

Смежные вопросы