SmartIterator.java
/*
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Utility class for applying limit and offset to a map or collection
*/
public class SmartIterator<A> {
private final int limit;
private final int offset;
public SmartIterator(int limit, int offset) {
this.limit = limit;
this.offset = offset;
}
/**
* Apply limit and offset to a map of value type {@link A}
*
* @param map
* the map
* @return the filtered map
*/
public Map<String, A> applyLimitAndOffset(Map<String, A> map) {
return limited(map.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new));
}
/**
* Apply limit and offset to a collection of type {@link A}
*
* @param unfilteredCollection
* the collection
* @return the filtered list
*/
public List<A> applyLimitAndOffset(Collection<A> unfilteredCollection) {
return limited(unfilteredCollection.stream()).collect(Collectors.toCollection(ArrayList::new));
}
/** Skip {@link #offset} elements, then take at most {@link #limit} of what remains ({@code 0} means no cap). */
private <T> Stream<T> limited(Stream<T> stream) {
if (limit < 0) {
return Stream.empty();
}
Stream<T> skipped = stream.skip(Math.max(offset, 0));
return limit == 0 ? skipped : skipped.limit(limit);
}
}