如何改变键值对?
我有一组值需要在需要时进行洗牌。 我不知道哪种变量类型最适合我。 数据实际上是基于键值结构。
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]