Monday, January 21, 2013

Java subList() for offset and limit

The other day I needed to limit the items in a list based on traditional offset and limit criteria. I could not find any on the net. And because it bears potential for little bugs I wrote a library function with unit tests. Here's my take:

/**
 * Returns a range of a list based on traditional offset/limit criteria.
 *
 * <p>Example:<pre>
 *   ListUtil.subList(Arrays.asList(1, 2, 3, 4, 5), 3, 5) => [4,5]
 * </pre></p>
 *
 * <p>In case the offset is higher than the list length the returned 
 * sublist is empty (no exception).
 * In case the list has fewer items than limit (with optional offset applied) 
 * then the remaining items
 * are returned (if any).</p>
 *
 * <p>Impl notes: returns a {@link List#subList} in all cases to have 
 * a consistent return value.</p>
 *
 * @param list The input list.
 * @param offset 0 for now offset, >=1 for an offset.
 * @param limit -1 for no limit, >=0 for how many items to return at most, 
 *              0 is allowed.
 */
public static <T> List<T> subList(List<T> list, int offset, int limit) {
    if (offset<0) throw new IllegalArgumentException("Offset must be >=0 but was "+offset+"!");
    if (limit<-1) throw new IllegalArgumentException("Limit must be >=-1 but was "+limit+"!");

    if (offset>0) {
        if (offset >= list.size()) {
            return list.subList(0, 0); //return empty.
        }
        if (limit >-1) {
            //apply offset and limit
            return list.subList(offset, Math.min(offset+limit, list.size()));
        } else {
            //apply just offset
            return list.subList(offset, list.size());
        }
    } else if (limit >-1) {
        //apply just limit
        return list.subList(0, Math.min(limit, list.size()));
    } else {
        return list.subList(0, list.size());
    }
}

2 comments:

  1. It seems there is a mistake in this line:

    if (offset<-1) throw new IllegalArgumentException("Limit must be >=-0 but was "+limit+"!");

    I don't think you want to check if offset is < -1. Probably you wanted to check limit?. Also, there is not -0, so I guess that you wanted to print "Limit must be >=-1", right?

    ReplyDelete
  2. Exactly! Thanks, fixed the post (and my code base).

    ReplyDelete