Java tutorial
//package com.java2s; /* Copyright (C) 2016 HermeneutiX.org This file is part of SciToS. SciToS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SciToS 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 General Public License for more details. You should have received a copy of the GNU General Public License along with SciToS. If not, see <http://www.gnu.org/licenses/>. */ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class Main { /** * Move a single entry (indicated by its key) up or down by one step inside an insert sorted map (e.g. a {@link LinkedHashMap}). * * @param <K> * type of the map's keys * @param <V> * type of the map's values * @param insertSortedMap * map containing the entry to be moved; should be a map implementation preserving the insert order (e.g. a {@link LinkedHashMap}) * @param entryKey * key of the entry to be moved up/down by one step * @param increaseIndexByOne * if the entry's index should be increased by one (i.e. moved down); otherwise decrease the entry's index by one (i.e. moved up) * @throws IllegalArgumentException * <ul> * <li>if the given map does not contain the specified key,</li> * <li>if the specified entry is the first in the map and cannot be moved further up, or</li> * <li>if the specified entry is the last in the map and cannot be moved further down</li> * </ul> */ public static <K, V> void moveEntryInInsertSortedMap(final Map<K, V> insertSortedMap, final K entryKey, final boolean increaseIndexByOne) { // #1 create a copy of the original key order as list (to make it accessible via index) final List<K> keyList = new ArrayList<K>(insertSortedMap.keySet()); // #2 determine the designated entry's current position final int index = keyList.indexOf(entryKey); // #3 determine the entry's new position final int indexToSwitchWith; if (increaseIndexByOne) { indexToSwitchWith = index + 1; } else { indexToSwitchWith = index - 1; } final int totalEntryCount = keyList.size(); if (index == -1 || indexToSwitchWith == -1 || indexToSwitchWith == totalEntryCount) { // the entry cannot be moved as indicated throw new IllegalArgumentException(); } // #4 create a copy of the unchanged relation template groups map final Map<K, V> groupsCopy = new LinkedHashMap<K, V>(insertSortedMap); // #5 remove all mapping from the original relation template groups map, starting at the affected groups' indices insertSortedMap.keySet().retainAll(keyList.subList(0, Math.min(index, indexToSwitchWith))); final K entryToSwitchWith = keyList.get(indexToSwitchWith); // #6 re-insert the two affected groups in their new (inverse) order if (increaseIndexByOne) { insertSortedMap.put(entryToSwitchWith, groupsCopy.get(entryToSwitchWith)); insertSortedMap.put(entryKey, groupsCopy.get(entryKey)); } else { insertSortedMap.put(entryKey, groupsCopy.get(entryKey)); insertSortedMap.put(entryToSwitchWith, groupsCopy.get(entryToSwitchWith)); } // #7 re-insert all groups that are following the affected two relation tempate groups final int firstTrailingRetainedIndex = Math.max(index, indexToSwitchWith) + 1; if (firstTrailingRetainedIndex < totalEntryCount) { // there is at least one more value behind the affected two entries that needs to be re-inserted groupsCopy.keySet().retainAll(keyList.subList(firstTrailingRetainedIndex, totalEntryCount)); insertSortedMap.putAll(groupsCopy); } } }