net.sourceforge.docfetcher.util.collect.MemoryList.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.docfetcher.util.collect.MemoryList.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Tran Nam Quang.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Tran Nam Quang - initial API and implementation
 *******************************************************************************/

package net.sourceforge.docfetcher.util.collect;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;

import com.google.common.collect.Lists;

import net.sourceforge.docfetcher.util.Util;
import net.sourceforge.docfetcher.util.annotations.NotNull;

/**
 * @author Tran Nam Quang
 */
public final class MemoryList<E> implements Collection<E> {

    /*
     * The internal list is sorted from most to least recently accessed.
     */
    private final LinkedList<E> list = new LinkedList<E>();
    private final int capacity;

    public MemoryList(int capacity) {
        Util.checkThat(capacity >= 0);
        this.capacity = capacity;
    }

    /**
     * Adds the given element to the receiver, with the following constraints:
     * <ul>
     * <li>New elements are placed at the beginning of the list.</li>
     * <li>If one attempts to add an element that is already in the list,
     * instead of duplication the existing element is moved to the beginning of
     * the list.</li>
     * <li>The list has a capacity limit. When that limit is reached, adding a
     * new elements leads to removal of the oldest element, which is at the end
     * of the list.</li>
     * </ul>
     */
    public boolean add(E e) {
        if (!list.isEmpty() && list.getFirst().equals(e))
            return false;
        list.remove(e);
        list.addFirst(e);
        if (list.size() > capacity)
            list.removeLast();
        return true;
    }

    /**
     * Has the same effect as iterating <b>backwards</b> over the given
     * collection and calling {@link #add(Object)} for each element.
     * <p>
     * The purpose of iterating backwards is to allow clients to use this method
     * for initializing the receiver with the given collection, so that the
     * order of the elements in the receiver is the same as in the given
     * collection, i.e. from most to least recently accessed.
     * 
     * @see #add(Object)
     */
    @SuppressWarnings("unchecked")
    public boolean addAll(Collection<? extends E> c) {
        List<E> list = c instanceof List ? (List<E>) c : new ArrayList<E>(c);
        boolean changed = false;
        for (E e : Lists.reverse(list))
            changed |= add(e);
        return changed;
    }

    /**
     * Returns the most recent element in the list. Throws a
     * {@link NoSuchElementException} if the list is empty.
     */
    @NotNull
    public E getMostRecent() {
        return list.getFirst();
    }

    public int size() {
        return list.size();
    }

    public boolean isEmpty() {
        return list.isEmpty();
    }

    public boolean contains(Object o) {
        return list.contains(o);
    }

    public Iterator<E> iterator() {
        return list.iterator();
    }

    public Object[] toArray() {
        return list.toArray();
    }

    public <T> T[] toArray(T[] a) {
        return list.toArray(a);
    }

    public boolean remove(Object o) {
        return list.remove(o);
    }

    public boolean containsAll(Collection<?> c) {
        return list.containsAll(c);
    }

    public boolean removeAll(Collection<?> c) {
        return list.removeAll(c);
    }

    public boolean retainAll(Collection<?> c) {
        return list.retainAll(c);
    }

    public void clear() {
        list.clear();
    }

}