/* * Priki - Prevalent Wiki * Copyright (c) 2005 Priki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * http://www.gnu.org/copyleft/gpl.html * * @author Vitor Fernando Pamplona - vitor@babaxp.org * */ package org.priki.utils; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * The same class existing in Jakarta Commons Collections => BAG. * * Defines a collection that counts the number of times an object appears in the collection. * Suppose you have a List that contains {a, b, b, c}. Putting into this Bag, the order will be {b, a, c} * * @author <a href="mailto:vitor@babaxp.org">Vitor Fernando Pamplona</a> * * @since 22/12/2005 * @version $Id: $ */ public class SortedBag<E extends Comparable<E>> implements Collection<E>, Iterable<E>, Serializable { public static final long serialVersionUID = 171L; private Map<E, BagItem> items = new HashMap<E, BagItem>(); public boolean add(E object) { BagItem item = items.get(object); if (item != null) item.times++; else items.put(object, new BagItem(object)); return true; } public boolean remove(Object object) { BagItem item = items.get(object); if (item == null) return false; if (item.times == 1) items.remove(object); else item.times--; return true; } public int getCount(E object) { BagItem item = items.get(object); if (item == null) return 0; return item.times; } private List<BagItem> getSortedList() { List<BagItem> sorted = new ArrayList<BagItem>(items.values()); Collections.sort(sorted); return sorted; } public Iterator<E> iterator() { List<BagItem> sorted = getSortedList(); return new BagIterator(sorted.iterator()); } public int size() { return items.size(); } public boolean isEmpty() { return items.isEmpty(); } public boolean contains(Object o) { return items.containsKey(o); } public Object[] toArray() { List<BagItem> list = getSortedList(); Object[] ret = new Object[list.size()]; for (int i=0; i<list.size(); i++) { ret[i] = list.get(i).obj; } return ret; } public <T> T[] toArray(T[] a) { throw new UnsupportedOperationException(); } public boolean containsAll(Collection<?> c) { for (Object e : c) { if (!contains(e)) return false; } return true; } public boolean addAll(Collection<? extends E> c) { for (E e : c) { add(e); } return true; } public boolean removeAll(Collection<?> c) { for (Object e : c) { remove(e); } return true; } public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } public void clear() { items.clear(); } /** * Each item of this collection * * @author <a href="mailto:vitor@babaxp.org">Vitor Fernando Pamplona</a> * * @since 20/12/2005 * @version $Id: $ */ class BagItem implements Comparable<BagItem>, Serializable { public static final long serialVersionUID = 174L; public E obj; public int times = 1; public BagItem(E obj) { this.obj = obj; } public boolean equals(Object o) { return obj.equals(((BagItem)o).obj); } public int hashCode() { return obj.hashCode(); } public int compareTo(BagItem o) { if (times < o.times) return 1; if (times > o.times) return -1; return obj.compareTo(o.obj); } } class BagIterator implements Iterator<E>, Serializable { public static final long serialVersionUID = 175L; private Iterator<BagItem> i; public BagIterator(Iterator<BagItem> i) { this.i = i; } public boolean hasNext() { return i.hasNext(); } public E next() { return i.next().obj; } public void remove() { i.remove(); } } }