blob: 6a3ff3a6a38debca2115fb39edca55ffb5ea6075 [file] [log] [blame]
/*
* Copyright (c) 2008-2012, 2014, 2015 Eike Stepper (Berlin, Germany) and others.
* 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:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.net4j.util.collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @author Eike Stepper
*/
public final class HashBag<T> implements Set<T>
{
private Map<T, Counter> map;
public HashBag()
{
map = new HashMap<T, Counter>();
}
public HashBag(int initialCapacity, float loadFactor)
{
map = new HashMap<T, Counter>(initialCapacity, loadFactor);
}
public HashBag(int initialCapacity)
{
map = new HashMap<T, Counter>(initialCapacity);
}
public HashBag(Map<? extends T, ? extends Counter> m)
{
map = new HashMap<T, Counter>(m);
}
/**
* @since 3.0
*/
public int getCounterFor(T o)
{
Counter counter = map.get(o);
if (counter == null)
{
return 0;
}
return counter.getValue();
}
public boolean add(T o)
{
return add(o, 1);
}
/**
* @since 3.4
*/
public boolean add(T o, int count)
{
Counter counter = map.get(o);
if (counter == null)
{
counter = new Counter(count);
map.put(o, counter);
return true;
}
counter.incValue(count);
return false;
}
public boolean addAll(Collection<? extends T> c)
{
for (T t : c)
{
add(t);
}
return true;
}
public void clear()
{
map.clear();
}
public boolean contains(Object o)
{
return map.containsKey(o);
}
public boolean containsAll(Collection<?> c)
{
return map.keySet().containsAll(c);
}
public boolean isEmpty()
{
return map.isEmpty();
}
public Iterator<T> iterator()
{
return map.keySet().iterator();
}
public boolean remove(Object o)
{
return remove(o, 1);
}
/**
* @since 3.4
*/
public boolean remove(Object o, int count)
{
Counter counter = map.get(o);
if (counter == null)
{
return false;
}
if (counter.decValue(count) <= 0)
{
map.remove(o);
}
return true;
}
public boolean removeAll(Collection<?> c)
{
boolean changed = false;
for (Object object : c)
{
if (remove(object))
{
changed = true;
}
}
return changed;
}
public boolean retainAll(Collection<?> c)
{
throw new UnsupportedOperationException();
}
public int size()
{
return map.size();
}
public Object[] toArray()
{
return map.keySet().toArray();
}
@SuppressWarnings("hiding")
public <T> T[] toArray(T[] a)
{
return map.keySet().toArray(a);
}
@Override
public String toString()
{
return map.toString();
}
/**
* @author Eike Stepper
*/
private static final class Counter
{
private int value;
public Counter(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
public int incValue(int count)
{
return value += count;
}
public int decValue(int count)
{
return value -= count;
}
@Override
public String toString()
{
return Integer.toString(value);
}
}
}