diff --git a/common/source/java/ch/systemsx/cisd/common/collections/GroupByMap.java b/common/source/java/ch/systemsx/cisd/common/collections/GroupByMap.java new file mode 100644 index 0000000000000000000000000000000000000000..c62cf97db7f323ab9724f60e16549c365e88e2c8 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/collections/GroupByMap.java @@ -0,0 +1,79 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.collections; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * A map which groups all elements added at the same key. + * + * @author Tomasz Pylak + */ +public class GroupByMap<K, E> +{ + private final Map<K, List<E>> map; + + private final IKeyExtractor<K, E> extractor; + + /** @param extractor computes a key for the row */ + public GroupByMap(final IKeyExtractor<K, E> extractor) + { + this.extractor = extractor; + this.map = new HashMap<K, List<E>>(); + } + + /** Creates a map for the specified rows with a given key extractor. */ + public static <K, E> GroupByMap<K, E> create(final Iterable<E> rows, + final IKeyExtractor<K, E> extractor) + { + GroupByMap<K, E> table = new GroupByMap<K, E>(extractor); + for (E row : rows) + { + table.add(row); + } + return table; + } + + /** Adds a new row. */ + public void add(E row) + { + K key = extractor.getKey(row); + List<E> elements = map.get(key); + if (elements == null) + { + elements = new ArrayList<E>(); + } + elements.add(row); + map.put(key, elements); + } + + /** Returns all rows added at the specified key. */ + public List<E> tryGet(K key) + { + return map.get(key); + } + + /** @return all available keys */ + public Set<K> getKeys() + { + return map.keySet(); + } +} diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/collections/GroupByMapTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/collections/GroupByMapTest.java new file mode 100644 index 0000000000000000000000000000000000000000..61ee70f5243425deada2911641947ce0219079b9 --- /dev/null +++ b/common/sourceTest/java/ch/systemsx/cisd/common/collections/GroupByMapTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.collections; + +import java.util.Arrays; +import java.util.List; + +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +/** + * Tests of {@link GroupByMap}. + * + * @author Tomasz Pylak + */ +public class GroupByMapTest extends AssertJUnit +{ + private IKeyExtractor<Integer, Integer> createKeyExtractor() + { + return new IKeyExtractor<Integer, Integer>() + { + public Integer getKey(Integer e) + { + return e; + } + }; + } + + @Test + public void test() + { + List<Integer> list = Arrays.asList(new Integer[] + { 1, 100, 1, 5, 100, 100 }); + GroupByMap<Integer, Integer> map = GroupByMap.create(list, createKeyExtractor()); + assertNull(map.tryGet(9)); + + List<Integer> list100 = map.tryGet(100); + assertNotNull(list100); + assertEquals(3, list100.size()); + + List<Integer> list5 = map.tryGet(5); + assertNotNull(list5); + assertEquals(1, list5.size()); + } +}