001/* 002 * (C) Copyright 2018 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.common.utils; 020 021import java.util.ArrayList; 022import java.util.List; 023import java.util.function.BiPredicate; 024import java.util.function.Function; 025 026import org.apache.commons.lang3.tuple.Pair; 027 028/** 029 * Batching utilities. 030 * 031 * @since 10.10 032 */ 033public class BatchUtils { 034 035 private BatchUtils() { 036 // utility class 037 } 038 039 /** 040 * Takes the input {@code values} and batches them together in groups. All values in a given group have the same 041 * derived value. The derived value is computed using the {@code deriver} function. Two derived values are compared 042 * for equality using the {@code comparator}. 043 * 044 * @param <T> the type of the values 045 * @param <U> the type of the derived values 046 * @param values the input values 047 * @param deriver the function to compute a derived value 048 * @param comparator the equality test for derived values 049 * @return a list of pairs with a derived values and the corresponding batch 050 * @since 10.10 051 */ 052 public static <T, U> List<Pair<U, List<T>>> groupByDerived(List<T> values, Function<T, U> deriver, 053 BiPredicate<U, U> comparator) { 054 List<Pair<U, List<T>>> result = new ArrayList<>(); 055 U previousDerived = null; 056 List<T> batch = null; 057 for (T value : values) { 058 U derived = deriver.apply(value); 059 if (batch == null || !comparator.test(derived, previousDerived)) { 060 // start new batch 061 batch = new ArrayList<>(); 062 result.add(Pair.of(derived, batch)); 063 } 064 // add to current batch 065 batch.add(value); 066 previousDerived = derived; 067 } 068 return result; 069 } 070 071}