001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.utils.collection;
015
016import java.util.Collections;
017import java.util.Comparator;
018import java.util.LinkedHashMap;
019import java.util.LinkedList;
020import java.util.List;
021import java.util.Map;
022
023public class MapUtils {
024
025  private MapUtils() {
026    throw new UnsupportedOperationException("Can't initialize class");
027  }
028
029  /**
030   * This orders a Map by its values and returns a new {@link LinkedHashMap} which maintains that order.
031   *
032   * @param map to sort
033   * @param <K> type of the map key
034   * @param <V> type of the map value, this needs to implement {@link Comparable}
035   *
036   * @return a map ordered by the values of the input map
037   */
038  public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
039    return sortByValueInternal(
040        map,
041        new Comparator<Map.Entry<K, V>>() {
042          @Override
043          public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
044            return o1.getValue().compareTo(o2.getValue());
045          }
046        });
047  }
048
049  /**
050   * Order a Map by its values using the given value comparator and return a new {@link LinkedHashMap} which maintains that order.
051   *
052   * @param map to sort
053   * @param <K> type of the map key
054   * @param <V> type of the map value
055   *
056   * @return a map ordered by the values of the input map
057   */
058  public static <K, V> Map<K, V> sortByValue(Map<K, V> map, final Comparator<V> comparator) {
059    return sortByValueInternal(
060        map,
061        new Comparator<Map.Entry<K, V>>() {
062          @Override
063          public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
064            return comparator.compare(o1.getValue(), o2.getValue());
065          }
066        });
067  }
068
069  private static <K, V> Map<K, V> sortByValueInternal(
070      Map<K, V> map, final Comparator<Map.Entry<K, V>> comp) {
071    List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
072    Collections.sort(list, comp);
073
074    Map<K, V> result = new LinkedHashMap<K, V>(list.size());
075    for (Map.Entry<K, V> entry : list) {
076      result.put(entry.getKey(), entry.getValue());
077    }
078    return result;
079  }
080
081  /**
082   * Returns a maps value or a given default if not present.
083   * For pre java8 code since j8 introduced Map.getOrDefault.
084   */
085  public static <K, V> V getOrDefault(Map<K, V> map, K key, V defaultValue) {
086    return map.containsKey(key) ? map.get(key) : defaultValue;
087  }
088}