2010-05-07 2 views
1

я есть LinkedHashMap и мне нужно переставлять (изменить ключ из значений) между 2 случайными значениямипереставлять данные для HashMap в Java

пример:

Ключ 1 Значение Значение 123 клавиша 2 456 ключ 3 значение 789

после случайной перестановки 2 значений

ключ 1 значение 123 клавиша 2 значения значения 789 ключа 3 456

поэтому здесь перестановочные значения между ключом 2 и ключом 3

спасибо;

образец кода моей карты:

Map map = new LinkedHashMap(); 
     map =myMap.getLinkedHashMap(); 

     Set key = map.keySet(); 

    for(Iterator it = cles.iterator(); it.hasNext();) 
    { 
     Integer cle = it.next(); 
     ArrayList values = (ArrayList)map.get(cle);//an arrayList of integers 

     int i = 0; 
     while(i < values.size()) 
     { 
      //i donno what to do here 
      i++; 
     } 
    } 
+1

Это домашнее задание? –

+0

nop Я работаю над проектом – Eddinho

ответ

1

Поскольку это не домашнее задание, вот мое решение. Обменивать себе является эффективным, но случайная выборка из 2-х предметов может быть улучшена :)

private static Random rnd = new Random(); 
... 
public static <K,V> void swapTwoRandomValues(Map<K,V> map){ 
    if (map.size() <= 1) 
     throw new IllegalArgumentException("Not enough items"); 

    //Choose 2 random positions pos1<pos2 
    int pos1 = 0, pos2 = 0; 
    while (pos1 == pos2){ 
     pos1 = rnd.nextInt(map.size()); 
     pos2 = rnd.nextInt(map.size()); 
    }  
    if (pos1 > pos2){ 
     int aux = pos1; 
     pos1 = pos2; 
     pos2 = aux; 
    } 

    //Fetch the entries 
    Iterator<Map.Entry<K, V>> it = map.entrySet().iterator(); 
    Map.Entry<K, V> entry1 = null; 
    for(int i=0;i <= pos1;i++) 
     entry1 = it.next(); 
    Map.Entry<K, V> entry2 = null; 
    for(int i = pos1;i < pos2;i++) 
     entry2 = it.next(); 

    //Swap values 
    V tmpValue = entry1.getValue(); 
    entry1.setValue(entry2.getValue()); 
    entry2.setValue(tmpValue); 
} 
2

Во-первых, вы должны использовать общие коллекции:

Map<Integer, List<Integer>> map = new LinkedHashMap<Integer, List<Integer>>(); 

Поскольку это выглядит как домашнее задание, я стараюсь давать подсказки, чтобы помочь вам вперед , а не полное решение. StackOverflow не должен писать домашнее задание для вас :-)

Вам нужны ключи от двух элементов для обмена. После этого вам просто нужно получить значения, соответствующие заданным ключам, и поменять их между двумя ключами. Затем добавьте случайную генерацию ключей - улучшение на @ общее решение Эяль в:

class MapSwapper1 { 
    private static Random rnd = new Random(); 
    private static K[] nullArray = new K[0]; 

    public static <K,V> void swapTwoRandomValues(Map<K,V> map){ 
     if (map.size() <= 1) 
     throw new IllegalArgumentException("Not enough items"); 

     //Choose 2 random positions pos1<pos2 
     int pos1 = 0, pos2 = 0; 
     while (pos1 == pos2) { 
     pos1 = rnd.nextInt(map.size()); 
     pos2 = rnd.nextInt(map.size()); 
     } 
     // Get the keys into an indexable array 
     K[] keys = map.keySet().toArray(nullArray); 

     swap(map, keys[pos1], keys[pos2]); 
    } 

    private static void <K,V> swap(Map<K, V> map, K key1, K key2) { 
     V tmp = map.get(key1); 
     map.put(key1, map.get(key2)); 
     map.put(key2, tmp); 
    } 
    } 

Я думаю, что это решение может быть быстрее, чем его даже, как это. Однако, если вы меняете значения внутри одной и той же карты много раз, не изменяя в противном случае карту (т. Е. Никакие ключи не добавляются, не удаляются или не изменяются на карте), вы можете дополнительно оптимизировать решение, повторно используя массив keys между последующими вызовами свопинга:

class MapSwapper2<K, V> { 
    private Random rnd = new Random(); 
    private Map<K,V> map; 
    private K[] keys; 

    public MapSwapper2(Map<K, V> map) { 
     resetKeys(); 
     this.map = map; 
    } 

    public void resetKeys() { 
     if (map.size() <= 1) 
     throw new IllegalArgumentException("Not enough items"); 
     keys = map.keySet().toArray(new K[0]); 
    } 

    public void swapTwoRandomValues() { 
     if (map.size() != keys.length) 
     resetKeys(); 

     //Choose 2 random positions pos1<pos2 
     int pos1 = 0, pos2 = 0; 
     while (pos1 == pos2) { 
     pos1 = rnd.nextInt(map.size()); 
     pos2 = rnd.nextInt(map.size()); 
     } 
     swap(map, keys[pos1], keys[pos2]); 
    } 

    private void swap(K key1, K key2) { 
     V tmp = map.get(key1); 
     map.put(key1, map.get(key2)); 
     map.put(key2, tmp); 
    } 
    } 

Как вы видите, объекты MapSwapper2 связаны с конкретным экземпляром карты, элементы которого они могут повторно менять. Метод resetKeys следует вызывать, если ключи карты изменены. Swapper может определить, изменился ли размер карты, но не, если, например, ключ удален и добавлен еще один ключ.

+0

спасибо, но это не домашнее задание lol, я работаю над проектом (планирование полета), перестановка будет результатом изменения назначения флота. arraylist integer, который я хочу переставить, - это полеты типа флота (ключ - тип флота) и значение массива полетов ... – Eddinho

+0

@tuxou, отлично, тогда см. Мое решение :-) –

+0

@ Péter, спасибо, что, если я хочу пересекать между 2 картами отец/motrher => сын, это с тем же методом? – Eddinho

1

Заметил несколько человек набрали что-то уже, но это достаточно полно, это не самый эффективный код, но это поможет вы на своем пути и вернете значения обратно на карту.

Map<Integer, Integer> map = new LinkedHashMap<Integer, Integer>(); 
    map.put(1, 123); 
    map.put(2, 456); 
    map.put(3, 789); 

    for (Entry<Integer, Integer> entry : map.entrySet()) 
     System.out.println("old key: " + entry.getKey() + " and value: " + entry.getValue()); 

    List<Integer> values = new ArrayList<Integer>(map.values()); 
    Collections.shuffle(values); 

    int i = 0; 
    for (Entry<Integer, Integer> entry : map.entrySet()) 
    { 
     map.put(entry.getKey(), values.get(i)); 
     i++; 
    } 

    for (Entry<Integer, Integer> entry : map.entrySet()) 
     System.out.println("new key: " + entry.getKey() + " and value: " + entry.getValue()); 
+0

Это не то, чего хотел OP. –