@@ -7275,7 +7275,7 @@ public final void forEach(final Action1<? super T> onNext, final Action1<Throwab
72757275 * @see <a href="http://reactivex.io/documentation/operators/groupby.html">ReactiveX operators documentation: GroupBy</a>
72767276 */
72777277 public final <K, R> Observable<GroupedObservable<K, R>> groupBy(final Func1<? super T, ? extends K> keySelector, final Func1<? super T, ? extends R> elementSelector) {
7278- return lift(new OperatorGroupBy <T, K, R>(keySelector, elementSelector));
7278+ return lift(new OperatorGroupByEvicting <T, K, R>(keySelector, elementSelector));
72797279 }
72807280
72817281 /**
@@ -7334,7 +7334,12 @@ public final <K, R> Observable<GroupedObservable<K, R>> groupBy(final Func1<? su
73347334 * if {@code evictingMapFactory} is null
73357335 * @see <a href="http://reactivex.io/documentation/operators/groupby.html">ReactiveX operators documentation: GroupBy</a>
73367336 * @since 1.3
7337+ * @deprecated since 1.3.7, use {@link #groupBy(Func1, Func1, int, boolean, Func1)}
7338+ * instead which uses much less memory. Please take note of the
7339+ * usage difference involving the evicting action which now expects
7340+ * the value from the map instead of the key.
73377341 */
7342+ @Deprecated
73387343 public final <K, R> Observable<GroupedObservable<K, R>> groupBy(final Func1<? super T, ? extends K> keySelector,
73397344 final Func1<? super T, ? extends R> elementSelector, final Func1<Action1<K>, Map<K, Object>> evictingMapFactory) {
73407345 if (evictingMapFactory == null) {
@@ -7369,6 +7374,72 @@ public final <K, R> Observable<GroupedObservable<K, R>> groupBy(final Func1<? su
73697374 *
73707375 * @param keySelector
73717376 * a function that extracts the key for each item
7377+ * @param elementSelector
7378+ * a function that extracts the return element for each item
7379+ * @param bufferSize
7380+ * the size of the buffer ({@link RxRingBuffer.SIZE} may be suitable).
7381+ * @param delayError
7382+ * if and only if false then onError emissions can shortcut onNext emissions (emissions may be buffered)
7383+ * @param evictingMapFactory
7384+ * a function that given an eviction action returns a {@link Map} instance that will be used to assign
7385+ * items to the appropriate {@code GroupedObservable}s. The {@code Map} instance must be thread-safe
7386+ * and any eviction must trigger a call to the supplied action (synchronously or asynchronously).
7387+ * This can be used to limit the size of the map by evicting entries by map maximum size or access time for
7388+ * instance. Here's an example using Guava's {@code CacheBuilder} from v24.0:
7389+ * <pre>
7390+ * {@code
7391+ * Func1<Action1<Object>, Map<K, Object>> mapFactory
7392+ * = action -> CacheBuilder.newBuilder()
7393+ * .maximumSize(1000)
7394+ * .expireAfterAccess(12, TimeUnit.HOURS)
7395+ * .removalListener(entry -> action.call(entry.getValue()))
7396+ * .<K, Object> build().asMap();
7397+ * }
7398+ * </pre>
7399+ *
7400+ * @param <K>
7401+ * the key type
7402+ * @param <R>
7403+ * the element type
7404+ * @return an {@code Observable} that emits {@link GroupedObservable}s, each of which corresponds to a
7405+ * unique key value and each of which emits those items from the source Observable that share that
7406+ * key value
7407+ * @throws NullPointerException
7408+ * if {@code evictingMapFactory} is null
7409+ * @see <a href="http://reactivex.io/documentation/operators/groupby.html">ReactiveX operators documentation: GroupBy</a>
7410+ * @since 1.3.7
7411+ */
7412+ @Experimental
7413+ public final <K, R> Observable<GroupedObservable<K, R>> groupBy(final Func1<? super T, ? extends K> keySelector,
7414+ final Func1<? super T, ? extends R> elementSelector, int bufferSize, boolean delayError,
7415+ final Func1<Action1<Object>, Map<K, Object>> evictingMapFactory) {
7416+ if (evictingMapFactory == null) {
7417+ throw new NullPointerException("evictingMapFactory cannot be null");
7418+ }
7419+ return lift(new OperatorGroupByEvicting<T, K, R>(
7420+ keySelector, elementSelector, bufferSize, delayError, evictingMapFactory));
7421+ }
7422+
7423+ /**
7424+ * Groups the items emitted by an {@code Observable} according to a specified criterion, and emits these
7425+ * grouped items as {@link GroupedObservable}s. The emitted {@code GroupedObservable} allows only a single
7426+ * {@link Subscriber} during its lifetime and if this {@code Subscriber} unsubscribes before the
7427+ * source terminates, the next emission by the source having the same key will trigger a new
7428+ * {@code GroupedObservable} emission.
7429+ * <p>
7430+ * <img width="640" height="360" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/groupBy.png" alt="">
7431+ * <p>
7432+ * <em>Note:</em> A {@link GroupedObservable} will cache the items it is to emit until such time as it
7433+ * is subscribed to. For this reason, in order to avoid memory leaks, you should not simply ignore those
7434+ * {@code GroupedObservable}s that do not concern you. Instead, you can signal to them that they may
7435+ * discard their buffers by applying an operator like {@link #ignoreElements} to them.
7436+ * <dl>
7437+ * <dt><b>Scheduler:</b></dt>
7438+ * <dd>{@code groupBy} does not operate by default on a particular {@link Scheduler}.</dd>
7439+ * </dl>
7440+ *
7441+ * @param keySelector
7442+ * a function that extracts the key for each item
73727443 * @param <K>
73737444 * the key type
73747445 * @return an {@code Observable} that emits {@link GroupedObservable}s, each of which corresponds to a
@@ -7377,7 +7448,7 @@ public final <K, R> Observable<GroupedObservable<K, R>> groupBy(final Func1<? su
73777448 * @see <a href="http://reactivex.io/documentation/operators/groupby.html">ReactiveX operators documentation: GroupBy</a>
73787449 */
73797450 public final <K> Observable<GroupedObservable<K, T>> groupBy(final Func1<? super T, ? extends K> keySelector) {
7380- return lift(new OperatorGroupBy <T, K, T>(keySelector));
7451+ return lift(new OperatorGroupByEvicting <T, K, T>(keySelector));
73817452 }
73827453
73837454 /**
0 commit comments