在 Java 中排列 HashMap 的数据

发布于 2024-08-31 22:16:03 字数 661 浏览 2 评论 0原文

我有一个 linkedhashmap,我需要在 2 个随机值之间排列(更改值的键)

示例:

键 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++;
        }
    }

i have a linkedhashmap and i need to permute (change the key of the values) between 2 random values

example :

key 1 value 123
key 2 value 456
key 3 value 789

after random permutation of 2 values

key 1 value 123
key 2 value 789
key 3 value 456

so here I permuted values between key 2 and key 3

thank you;

sample of the code of my map :

    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++;
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拍不死你 2024-09-07 22:16:03

首先,您应该使用通用集合:

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

由于这看起来像家庭作业,因此我尝试提供提示来帮助您前进,而不是提供完整的解决方案。 StackOverflow 不应该为您写作业 :-)

您需要交换两个元素的键。一旦你有了这个,你只需要获取与给定键对应的值并在两个键之间交换它们。然后添加随机密钥生成 - 改进@Eyal的通用解决方案:

  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 方法。交换器可以检测映射的大小是否已改变,但不能检测例如移除了一个键并添加了另一个键。

First, you should use generic collections:

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

Since this looks like homework, I try to give hints to help you forward, rather than a full solution. StackOverflow is not supposed to write your homework for you :-)

You need the keys of the two elements to swap. Once you have that, you just need to get the values corresponding to the given keys and swap them between the two keys. Then add the random key generation - improving on @Eyal's generic solution:

  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);
    }
  }

I think this solution may be faster than his even as it is. However, if you swap values within the same map many times without changing the map otherwise (i.e. no keys are added, removed or changed in the map), you can further optimize the solution by reusing the keys array between subsequent swap calls:

  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);
    }
  }

As you see, MapSwapper2 objects are associated with a specific map instance, whose elements they can repeatedly swap. The resetKeys method should be called if the map keys have changed. The swapper can detect if the size of the map has changed, but not if e.g. a key has been removed and another key added.

小女人ら 2024-09-07 22:16:03

由于这不是作业,这是我的解决方案。交换本身是高效的,但 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);
}

Since this is not homework, here is my solution. The swapping itself is efficient, but the random sampling of 2 items can be improved :)

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);
}
怕倦 2024-09-07 22:16:03

注意到有些人已经输入了一些内容,但这相当完整,它不是最有效的代码,但它将帮助您前进并将值放回地图中。

    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());

Noticed a few people typed up something already, but this is fairly complete, it's not the most efficient code but it will help you on your way and will put the values back in the map.

    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());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文