如何改变键值对?

我有一组值需要在需要时进行洗牌。 我不知道哪种变量类型最适合我。 数据实际上是基于键值结构。

100 "white" 200 "black" 300 "red" 

就像那样。 我想要做的是根据我还不知道更改键值对,一些算法。但是它们需要像这样改组,但是洗牌需要不是随机的 ,所以我可以在需要时还原数据。

 100 "red" 200 "white" 300 "black" 

我真的不知道我的方法应该如何解决。 我应该使用HashTable还是其他东西,我该如何动态地将它们混洗? 任何帮助表示赞赏

另一种随机改变键值映射的方法:

 public static  void shuffleMap(Map map) { List valueList = new ArrayList(map.values()); Collections.shuffle(valueList); Iterator valueIt = valueList.iterator(); for(Map.Entry e : map.entrySet()) { e.setValue(valueIt.next()); } } 

编辑:

如果您不想更改原始地图(因为之后需要它),您可以创建一个新地图:

 public static  Map shuffleMap(Map map) { List valueList = new ArrayList(map.values()); Collections.shuffle(valueList); Iterator valueIt = valueList.iterator(); Map newMap = new HashMap(map.size()); for(K key : map.keySet()) { newMap.put(key, valueIt.next()); } return newMap; } 

你真的不想要一个看似随意的混合,它可以被还原 (很快变得复杂),但只是保留原始地图。 如果这不适合,您需要更好地描述您的问题。


好的,您希望使用密钥加密映射,给出另一个映射,然后再次解密。 显然随机改组在这里没有用,甚至伪随机也没有用,因为它没有给出重新洗牌的可靠方法。 在基本情况下,您的密钥将是我们映射的键之间的可逆映射。

 public static  Map encryptMap(Map plainMap, Map key) { Map cryptoMap = new HashMap(plainMap.size()); for(Map.Entry entry : plainMap.entrySet()) { cryptoMap.put(key.get(entry.getKey()), entry.getValue()); } return cryptoMap; } 

事实上,解密工作原理相同,只使用密钥的反向映射。

因此,当您拥有{100, 200, 300}示例密钥时,这些密钥的任何排列都是我们“加密方案”的有效密钥。 (只有6种可能,但不是很安全。)

 Map sampleKey = new HashMap(); sampleKey.put(100, 200); sampleKey.put(200, 300); sampleKey.put(300, 100); Map sampleUnKey = new HashMap(); for(Map.Entry e : sampleKey) { sampleUnKey.put(e.getValue(), e.getKey()); } Map data = new HashMap(); data.put(100, "white"); data.put(200, "black"); data.put(300, "red"); System.out.println(data); Map encrypted = encryptMap(data, sampleKey); System.out.println(encrypted); Map decrypted = encryptMap(data, sampleUnKey); System.out.println(decrypted); 

现在decrypted的地图应该与原始地图相同。

对于更大的键集,您可能希望找到一个方案,以从一些可输入键中获得合适的键排列。

看起来你需要一个tupples列表。 地图就是这样。 但是,像HashMap这样的标准没有用于更改键和值之间关系的function。

我想我会为此实现自己的Map。 创建一个实现java.util.Map的类,实现所需的方法并创建一些“混合”的其他方法。

这一切都取决于你在tupples列表中真正需要的function。 你需要快速查找颜色吗? 可以有多个具有相同数字的tupple?

我不确定你将如何对这些对进行洗牌 ,但是如果你需要根据键对它们进行洗牌,你可以使用Map

 Map map = new HashMap(); map.put("100", "white"); map.put("200", "black"); map.put("300", "red"); // swap 100 with 200 String temp = map.get("100"); map.put("100", map.get("200")); map.put("200", temp); 

或者,如果您需要随机地对该对进行随机播放,您可以创建一个类Pair (基本上将存储一个int和一个String ),如larsmans所建议的那样,并将它们存储在一个数组中。 然后,可以使用略微修改的Fisher-Yates shuffle版本。 这些方面的东西:

 // initialize list List> values = new ArrayList>(); values.add(new Pair(100, "white")); values.add(new Pair(200, "black")); values.add(new Pair(300, "red")); // shuffle System.out.println(values); // eg, [100 white, 200 black, 300 red] Random random = new Random(); for (int i = values.size() - 1; i > 1; i--) { int j = random.nextInt(i + 1); // swap values between i-th Pair and j-th Pair Pair iPair = values.get(i); // the iPair :-) Pair jPair = values.get(j); String iString = iPair.getSecond(); iPair.setSecond(jPair.getSecond()); jPair.setSecond(iString); } System.out.println(values); // eg, [100 red, 200 black, 300 white]