001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.dllearner.utilities;
020
021import com.google.common.base.Joiner;
022import com.google.common.base.Strings;
023import com.google.common.collect.ArrayListMultimap;
024import com.google.common.collect.Multimap;
025import com.google.common.collect.TreeMultimap;
026import org.apache.commons.lang3.StringUtils;
027
028import java.util.*;
029import java.util.Map.Entry;
030
031/**
032 * Utility class for operations on maps.
033 *
034 * @author Lorenz Buehmann
035 */
036public class MapUtils {
037
038        /**
039         * Returns a list of entries sorted by the map values descending.
040         *
041         * @param map the map
042         * @return a list of entries sorted by the map values descending.
043         */
044        public static <K, V extends Comparable<V>> List<Entry<K, V>> sortByValues(Map<K, V> map) {
045                return sortByValues(map, false);
046        }
047
048        /**
049         * Returns a list of entries sorted by the map values either ascending or descending.
050         *
051         * @param map the map
052         * @return a list of entries sorted by the map values either ascending or descending.
053         */
054        public static <K, V extends Comparable<V>> List<Entry<K, V>> sortByValues(Map<K, V> map, final boolean ascending){
055                List<Entry<K, V>> entries = new ArrayList<>(map.entrySet());
056        Collections.sort(entries, new Comparator<Entry<K, V>>() {
057
058                        @Override
059                        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
060                                if(ascending){
061                                        return o1.getValue().compareTo(o2.getValue());
062                                } else {
063                                        return o2.getValue().compareTo(o1.getValue());
064                                }
065                        }
066                });
067        return entries;
068        }
069
070        /**
071         * Constructs a multimap with the same mappings as the specified map.
072         *
073         * @param input the input map
074         * @return the multimap
075         */
076        public static <K, V> Multimap<K, V> createMultiMap(Map<K, ? extends Iterable<V>> input) {
077                Multimap<K, V> multimap = ArrayListMultimap.create();
078                for (Map.Entry<K, ? extends Iterable<V>> entry : input.entrySet()) {
079                        multimap.putAll(entry.getKey(), entry.getValue());
080                }
081                return multimap;
082        }
083
084        /**
085         * Creates a Guava sorted multimap using the input map.
086         *
087         * @param input the input map
088         * @return the multimap
089         */
090        public static <K extends Comparable, V extends Comparable> Multimap<K, V> createSortedMultiMap(Map<K, ? extends Iterable<V>> input) {
091                Multimap<K, V> multimap = TreeMultimap.create();
092                for (Map.Entry<K, ? extends Iterable<V>> entry : input.entrySet()) {
093                        multimap.putAll(entry.getKey(), entry.getValue());
094                }
095                return multimap;
096        }
097
098        /**
099         * Return map in TSV format.
100         * @param map the map
101         * @param <K>
102         * @param <V>
103         * @return TSV formatted String
104         */
105        public static <K, V> String asTSV(Map<K, V> map) {
106                return Joiner.on("\n").withKeyValueSeparator("\t").join(map);
107        }
108
109        /**
110         * Return map in TSV format.
111         * @param map the map
112         * @param keyHeader header for key column
113         * @param valueHeader header for value column
114         * @param <K>
115         * @param <V>
116         *
117         * @return TSV formatted String
118         */
119        public static <K, V> String asTSV(Map<K, V> map, String keyHeader, String valueHeader) {
120                return Strings.nullToEmpty(keyHeader) + "\t" + Strings.nullToEmpty(valueHeader) + "\n" + Joiner.on("\n").withKeyValueSeparator("\t").join(map);
121        }
122}