Skip to content

Commit 73a191a

Browse files
Merge pull request ReactiveX#526 from benjchristensen/pull-513-toMap
Manual Merge of toMap/toMultiMap
2 parents 6222050 + ba57196 commit 73a191a

File tree

6 files changed

+1095
-0
lines changed

6 files changed

+1095
-0
lines changed

language-adaptors/rxjava-groovy/src/test/groovy/rx/lang/groovy/ObservableTests.groovy

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,143 @@ def class ObservableTests {
345345
assertEquals(6, count);
346346
}
347347

348+
@Test
349+
public void testToMap1() {
350+
Map actual = new HashMap();
351+
352+
Observable.from("a", "bb", "ccc", "dddd")
353+
.toMap({String s -> s.length()})
354+
.toBlockingObservable()
355+
.forEach({s -> actual.putAll(s); });
356+
357+
Map expected = new HashMap();
358+
expected.put(1, "a");
359+
expected.put(2, "bb");
360+
expected.put(3, "ccc");
361+
expected.put(4, "dddd");
362+
363+
assertEquals(expected, actual);
364+
}
365+
366+
@Test
367+
public void testToMap2() {
368+
Map actual = new HashMap();
369+
370+
Observable.from("a", "bb", "ccc", "dddd")
371+
.toMap({String s -> s.length()}, {String s -> s + s})
372+
.toBlockingObservable()
373+
.forEach({s -> actual.putAll(s); });
374+
375+
Map expected = new HashMap();
376+
expected.put(1, "aa");
377+
expected.put(2, "bbbb");
378+
expected.put(3, "cccccc");
379+
expected.put(4, "dddddddd");
380+
381+
assertEquals(expected, actual);
382+
}
383+
384+
@Test
385+
public void testToMap3() {
386+
Map actual = new HashMap();
387+
388+
LinkedHashMap last3 = new LinkedHashMap() {
389+
public boolean removeEldestEntry(Map.Entry e) {
390+
return size() > 3;
391+
}
392+
};
393+
394+
Observable.from("a", "bb", "ccc", "dddd")
395+
.toMap({String s -> s.length()}, {String s -> s + s}, { last3 })
396+
.toBlockingObservable()
397+
.forEach({s -> actual.putAll(s); });
398+
399+
Map expected = new HashMap();
400+
expected.put(2, "bbbb");
401+
expected.put(3, "cccccc");
402+
expected.put(4, "dddddddd");
403+
404+
assertEquals(expected, actual);
405+
}
406+
@Test
407+
public void testToMultimap1() {
408+
Map actual = new HashMap();
409+
410+
Observable.from("a", "b", "cc", "dd")
411+
.toMultimap({String s -> s.length()})
412+
.toBlockingObservable()
413+
.forEach({s -> actual.putAll(s); });
414+
415+
Map expected = new HashMap();
416+
417+
expected.put(1, Arrays.asList("a", "b"));
418+
expected.put(2, Arrays.asList("cc", "dd"));
419+
420+
assertEquals(expected, actual);
421+
}
422+
423+
@Test
424+
public void testToMultimap2() {
425+
Map actual = new HashMap();
426+
427+
Observable.from("a", "b", "cc", "dd")
428+
.toMultimap({String s -> s.length()}, {String s -> s + s})
429+
.toBlockingObservable()
430+
.forEach({s -> actual.putAll(s); });
431+
432+
Map expected = new HashMap();
433+
434+
expected.put(1, Arrays.asList("aa", "bb"));
435+
expected.put(2, Arrays.asList("cccc", "dddd"));
436+
437+
assertEquals(expected, actual);
438+
}
439+
440+
@Test
441+
public void testToMultimap3() {
442+
Map actual = new HashMap();
443+
444+
LinkedHashMap last1 = new LinkedHashMap() {
445+
public boolean removeEldestEntry(Map.Entry e) {
446+
return size() > 1;
447+
}
448+
};
449+
450+
Observable.from("a", "b", "cc", "dd")
451+
.toMultimap({String s -> s.length()}, {String s -> s + s}, { last1 })
452+
.toBlockingObservable()
453+
.forEach({s -> actual.putAll(s); });
454+
455+
Map expected = new HashMap();
456+
457+
expected.put(2, Arrays.asList("cccc", "dddd"));
458+
459+
assertEquals(expected, actual);
460+
}
461+
462+
@Test
463+
public void testToMultimap4() {
464+
Map actual = new HashMap();
465+
466+
LinkedHashMap last1 = new LinkedHashMap() {
467+
public boolean removeEldestEntry(Map.Entry e) {
468+
return size() > 2;
469+
}
470+
};
471+
472+
Observable.from("a", "b", "cc", "dd", "eee", "eee")
473+
.toMultimap({String s -> s.length()}, {String s -> s + s}, { last1 },
474+
{i -> i == 2 ? new ArrayList() : new HashSet() })
475+
.toBlockingObservable()
476+
.forEach({s -> actual.putAll(s); });
477+
478+
Map expected = new HashMap();
479+
480+
expected.put(2, Arrays.asList("cccc", "dddd"));
481+
expected.put(3, new HashSet(Arrays.asList("eeeeee")));
482+
483+
assertEquals(expected, actual);
484+
}
348485

349486
def class AsyncObservable implements OnSubscribeFunc {
350487

rxjava-core/src/main/java/rx/Observable.java

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
import java.util.ArrayList;
2121
import java.util.Arrays;
22+
import java.util.Collection;
2223
import java.util.Comparator;
2324
import java.util.List;
25+
import java.util.Map;
2426
import java.util.concurrent.ConcurrentHashMap;
2527
import java.util.concurrent.Future;
2628
import java.util.concurrent.TimeUnit;
@@ -87,6 +89,8 @@
8789
import rx.operators.OperationTimeInterval;
8890
import rx.operators.OperationTimeout;
8991
import rx.operators.OperationTimestamp;
92+
import rx.operators.OperationToMap;
93+
import rx.operators.OperationToMultimap;
9094
import rx.operators.OperationToObservableFuture;
9195
import rx.operators.OperationToObservableIterable;
9296
import rx.operators.OperationToObservableList;
@@ -5943,6 +5947,7 @@ public static <R> Observable<R> when(Plan0<R> p1, Plan0<R> p2, Plan0<R> p3, Plan
59435947
public static <R> Observable<R> when(Plan0<R> p1, Plan0<R> p2, Plan0<R> p3, Plan0<R> p4, Plan0<R> p5, Plan0<R> p6, Plan0<R> p7, Plan0<R> p8, Plan0<R> p9) {
59445948
return create(OperationJoinPatterns.when(p1, p2, p3, p4, p5, p6, p7, p8, p9));
59455949
}
5950+
59465951
/**
59475952
* Correlates the elements of two sequences based on overlapping durations.
59485953
* @param right The right observable sequence to join elements for.
@@ -5964,5 +5969,128 @@ public <TRight, TLeftDuration, TRightDuration, R> Observable<R> join(Observable<
59645969
Func2<T, TRight, R> resultSelector) {
59655970
return create(new OperationJoin<T, TRight, TLeftDuration, TRightDuration, R>(this, right, leftDurationSelector, rightDurationSelector, resultSelector));
59665971
}
5972+
5973+
/**
5974+
* Return an Observable that emits a single HashMap containing all items
5975+
* emitted by the source Observable, mapped by the keys returned by the
5976+
* {@code keySelector} function.
5977+
*
5978+
* If a source item maps to the same key, the HashMap will contain the latest
5979+
* of those items.
5980+
*
5981+
* @param keySelector the function that extracts the key from the source items
5982+
* to be used as keys in the HashMap.
5983+
* @return an Observable that emits a single HashMap containing the mapped
5984+
* values of the source Observable
5985+
* @see <a href='http://msdn.microsoft.com/en-us/library/hh229137(v=vs.103).aspx'>MSDN: Observable.ToDictionary</a>
5986+
*/
5987+
public <K> Observable<Map<K, T>> toMap(Func1<? super T, ? extends K> keySelector) {
5988+
return create(OperationToMap.toMap(this, keySelector));
5989+
}
5990+
5991+
/**
5992+
* Return an Observable that emits a single HashMap containing elements with
5993+
* key and value extracted from the values emitted by the source Observable.
5994+
*
5995+
* If a source item maps to the same key, the HashMap will contain the latest
5996+
* of those items.
5997+
*
5998+
* @param keySelector the function that extracts the key from the source items
5999+
* to be used as key in the HashMap
6000+
* @param valueSelector the function that extracts the value from the source items
6001+
* to be used as value in the HashMap
6002+
* @return an Observable that emits a single HashMap containing the mapped
6003+
* values of the source Observable
6004+
* @see <a href='http://msdn.microsoft.com/en-us/library/hh212075(v=vs.103).aspx'>MSDN: Observable.ToDictionary</a>
6005+
*/
6006+
public <K, V> Observable<Map<K, V>> toMap(Func1<? super T, ? extends K> keySelector, Func1<? super T, ? extends V> valueSelector) {
6007+
return create(OperationToMap.toMap(this, keySelector, valueSelector));
6008+
}
6009+
6010+
/**
6011+
* Return an Observable that emits a single Map, returned by the mapFactory function,
6012+
* containing key and value extracted from the values emitted by the source Observable.
6013+
*
6014+
* @param keySelector the function that extracts the key from the source items
6015+
* to be used as key in the Map
6016+
* @param valueSelector the function that extracts the value from the source items
6017+
* to be used as value in the Map
6018+
* @param mapFactory the function that returns an Map instance to be used
6019+
* @return an Observable that emits a single Map containing the mapped
6020+
* values of the source Observable
6021+
*/
6022+
public <K, V> Observable<Map<K, V>> toMap(Func1<? super T, ? extends K> keySelector, Func1<? super T, ? extends V> valueSelector, Func0<? extends Map<K, V>> mapFactory) {
6023+
return create(OperationToMap.toMap(this, keySelector, valueSelector, mapFactory));
6024+
}
6025+
6026+
/**
6027+
* Return an Observable that emits a single HashMap containing an ArrayList of elements,
6028+
* emitted by the source Observable and keyed by the keySelector function.
6029+
*
6030+
* @param keySelector the function that extracts the key from the source items
6031+
* to be used as key in the HashMap
6032+
* @return an Observable that emits a single HashMap containing an ArrayList of elements
6033+
* mapped from the source Observable
6034+
* @see <a href='http://msdn.microsoft.com/en-us/library/hh212098(v=vs.103).aspx'>MSDN: Observable.ToLookup</a>
6035+
*/
6036+
public <K> Observable<Map<K, Collection<T>>> toMultimap(Func1<? super T, ? extends K> keySelector) {
6037+
return create(OperationToMultimap.toMultimap(this, keySelector));
6038+
}
6039+
6040+
/**
6041+
* Return an Observable that emits a single HashMap containing an ArrayList of values,
6042+
* extracted by the valueSelector function, emitted by the source Observable
6043+
* and keyed by the keySelector function.
6044+
*
6045+
* @param keySelector the function that extracts the key from the source items
6046+
* to be used as key in the HashMap
6047+
* @param valueSelector the function that extracts the value from the source items
6048+
* to be used as value in the Map
6049+
* @return an Observable that emits a single HashMap containing an ArrayList of elements
6050+
* mapped from the source Observable
6051+
*
6052+
* @see <a href='http://msdn.microsoft.com/en-us/library/hh229101(v=vs.103).aspx'>MSDN: Observable.ToLookup</a>
6053+
*/
6054+
public <K, V> Observable<Map<K, Collection<V>>> toMultimap(Func1<? super T, ? extends K> keySelector, Func1<? super T, ? extends V> valueSelector) {
6055+
return create(OperationToMultimap.toMultimap(this, keySelector, valueSelector));
6056+
}
6057+
6058+
/**
6059+
* Return an Observable that emits a single Map, returned by the mapFactory function,
6060+
* containing an ArrayList of values, extracted by the valueSelector function,
6061+
* emitted by the source Observable and keyed by the
6062+
* keySelector function.
6063+
*
6064+
* @param keySelector the function that extracts the key from the source items
6065+
* to be used as key in the Map
6066+
* @param valueSelector the function that extracts the value from the source items
6067+
* to be used as value in the Map
6068+
* @param mapFactory the function that returns an Map instance to be used
6069+
* @return an Observable that emits a single Map containing the list of mapped values
6070+
* of the source observable.
6071+
*/
6072+
public <K, V> Observable<Map<K, Collection<V>>> toMultimap(Func1<? super T, ? extends K> keySelector, Func1<? super T, ? extends V> valueSelector, Func0<? extends Map<K, Collection<V>>> mapFactory) {
6073+
return create(OperationToMultimap.toMultimap(this, keySelector, valueSelector, mapFactory));
6074+
}
6075+
6076+
/**
6077+
* Return an Observable that emits a single Map, returned by the mapFactory function,
6078+
* containing a custom collection of values, extracted by the valueSelector function,
6079+
* emitted by the source Observable and keyed by the
6080+
* keySelector function.
6081+
*
6082+
* @param keySelector the function that extracts the key from the source items
6083+
* to be used as key in the Map
6084+
* @param valueSelector the function that extracts the value from the source items
6085+
* to be used as value in the Map
6086+
* @param mapFactory the function that returns an Map instance to be used
6087+
* @param collectionFactory the function that returns a Collection instance for
6088+
* a particular key to be used in the Map
6089+
* @return an Observable that emits a single Map containing the collection of mapped values
6090+
* of the source observable.
6091+
*/
6092+
public <K, V> Observable<Map<K, Collection<V>>> toMultimap(Func1<? super T, ? extends K> keySelector, Func1<? super T, ? extends V> valueSelector, Func0<? extends Map<K, Collection<V>>> mapFactory, Func1<? super K, ? extends Collection<V>> collectionFactory) {
6093+
return create(OperationToMultimap.toMultimap(this, keySelector, valueSelector, mapFactory, collectionFactory));
6094+
}
59676095
}
59686096

0 commit comments

Comments
 (0)