java - 如何打乱键值对?

标签 java key-value

我有一组值需要在需要时进行打乱。 我不知道哪种变量类型最适合我。数据实际上是基于key-value结构的。比如;

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

就这样。我想做的是根据我还不知道的某种算法来更改键值对。但是它们需要像这样进行洗牌,但是洗牌需要不是随机,所以我可以在需要时恢复数据。

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

我真的不知道我的解决方案应该如何。我应该使用 HashTable 还是其他东西,以及如何动态地对它们进行洗牌? 感谢任何帮助

最佳答案

随机打乱键值映射的另一种方法:

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

编辑:

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

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

您并不真正想要可以恢复的看似随机的混合(这很快就会变得复杂),而只是保留原始 map 。如果这不合适,您需要更好地描述您的问题。


好吧,您想使用 key 加密映射,提供另一个映射,然后再次解密。显然,随机洗牌在这里没有帮助,甚至伪随机也不好,因为它没有提供可靠的洗牌方法。在基本情况下,您的 key 将是我们映射的 key 之间的可逆映射。

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

解密的原理是一样的,事实上,只是使用 key 的反向映射。

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

Map sampleKey = new HashMap<Integer, Integer>();
sampleKey.put(100, 200);
sampleKey.put(200, 300);
sampleKey.put(300, 100);

Map sampleUnKey = new HashMap<Integer, Integer>();
for(Map.Entry<Integer, Integer> e : sampleKey) {
   sampleUnKey.put(e.getValue(), e.getKey());
}

Map<Integer, String> data = new HashMap<Integer, String>();
data.put(100, "white");
data.put(200, "black");
data.put(300, "red");

System.out.println(data);

Map<Integer, String> encrypted = encryptMap(data, sampleKey);

System.out.println(encrypted);

Map<Integer, String> decrypted = encryptMap(data, sampleUnKey);

System.out.println(decrypted);

现在解密的 map 应该与原始 map 相同。

对于更大的键集,您需要找到一个方案来获得合适的 来自某些可输入键的键排列。

关于java - 如何打乱键值对?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5289222/

相关文章:

c# - 如何重新编号 ObservableCollection<KeyValuePair<int, string>

mysql - 为什么这个 "Mysql"查询偶尔会挂起一次?

python - 在Python字典列表中查找相同键值对的最佳方法

java - RichFaces中Ajax请求的取消

Android - 除了值之外,如何从 JSON 获取键名

java - 如何在java中使用数组在一行中设置多个选择条件?

java - 在 Eclipse java 调试器中隐藏不存在的变量

python - zip 中的键和值

java - 我是否应该考虑对 Spring Rest Controller 层使用 DTO 而不是实体?

java - 如何将对象从android手机发送到servlet?