/* * Concept profile generation tool suite * Copyright (C) 2015 Biosemantics Group, Erasmus University Medical Center, * Rotterdam, The Netherlands * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package org.erasmusmc.collections; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Set; import org.erasmusmc.utilities.StringUtilities; public class SortedListSet<K> implements Set<K>,Serializable { private static final long serialVersionUID = -3522054629441473877L; protected List<K> setEntries; protected Comparator<K> comparator; public String toString(){ StringBuffer result = new StringBuffer("["); result.append(StringUtilities.join(setEntries,",")); result.append("]"); return result.toString(); } public SortedListSet(Comparator<K> comparator) { this.comparator = comparator; setEntries = new ArrayList<K>(); } public SortedListSet(Comparator<K> comparator,List<K> setEntries) { //if you use this constructor: know what you are doing! //the list is expected to be sorted exactly as would be done by the //given comparator! this.comparator = comparator; this.setEntries = setEntries; } public Comparator<K> getComparator(){ return comparator; } public Iterator<K> iterator() { return new Iterator<K> () { int index = 0; public boolean hasNext() { return index < setEntries.size(); } public K next() { return setEntries.get(index++); } public void remove() { } }; } public boolean add(K key) { int index = binarySearch(key); if (index < setEntries.size()) { K k = setEntries.get(index); if (comparator.compare(key, k) == 0){ setEntries.set(index,key); } else setEntries.add(index, key); } else setEntries.add(index, key); //err... always true? return true; } protected int binarySearch(K key) { int low = 0, middle, high = setEntries.size(); while (low < high) { middle = (low + high) / 2; if (comparator.compare(key, setEntries.get(middle)) > 0) low = middle + 1; else high = middle; } return low; } public int size() { return setEntries.size(); } public void clear() { setEntries.clear(); } public boolean isEmpty() { if (setEntries.size()==0){ return true; } else{ return false; } } @SuppressWarnings("unchecked") public boolean contains(Object key) { //listen, if you're going to be so stupid to put //an object in here which is not of type K, all weird shit is going to happen. //Don't look at me then! //love Rob int index = binarySearch((K)key); if (index < setEntries.size()) { K k = setEntries.get(index); if (comparator.compare((K)key, k) == 0){ return true; } else return false; } else return false; } /**This is a special function if you know FOR SURE that you have a list sorted *according to how the Comparator would sort, and you would like to set it * as the list underlying the set. Note that the old list is lost.*/ public void setSortedList(List<K> list){ setEntries = list; } /**This returns the precious sorted list: Don't fuck it up! (please)*/ public List<K> getSortedList(){ return setEntries; } public Object[] toArray() { return setEntries.toArray(); } @SuppressWarnings("unchecked") public Object[] toArray(Object[] arg0) { return setEntries.toArray(arg0); } @SuppressWarnings("unchecked") public boolean remove(Object key) { int index = binarySearch((K)key); if (index < setEntries.size()) { K k = setEntries.get(index); if (comparator.compare((K)key, k) == 0){ setEntries.remove(index); return true; } else return false; } else return false; } public boolean containsAll(Collection<?> arg0) { Iterator<?> iterator = arg0.iterator(); while (iterator.hasNext()){ if(!contains(iterator.next())){ return false; } } return true; } public boolean addAll(Collection<? extends K> arg0) { Iterator<? extends K> iterator = arg0.iterator(); while (iterator.hasNext()){ add(iterator.next()); } return true; } @SuppressWarnings("unchecked") public boolean retainAll(Collection<?> arg0) { //not very efficient!! List<K> temp = new ArrayList<K>(); Iterator<?> iterator = arg0.iterator(); while (iterator.hasNext()){ Object object = iterator.next(); if (contains(object)){ temp.add((K)object); } } setEntries = temp; return true; } public boolean removeAll(Collection<?> arg0) { Iterator<?> iterator = arg0.iterator(); while (iterator.hasNext()){ remove(iterator.next()); } return true; } public static Comparator<Integer> getAscendingIntegerComparator(){ return new Comparator<Integer>(){ public int compare(Integer arg0, Integer arg1) { return arg0-arg1; } }; } }