【问题标题】:How to get certain values from ArrayList and put them in a map如何从 ArrayList 中获取某些值并将它们放在地图中
【发布时间】:2021-10-06 12:39:04
【问题描述】:

我有一个程序,其中有 52 张牌和 int 玩家数(例如让我们从 4 人开始),任务要求我将这样的元素放入 Map 的地图中:

{Player 1=[51, 47, 43, 39, 35, 31, 27, 23, 19, 15, 11, 7, 3], " +
"Player 2=[50, 46, 42, 38, 34, 30, 26, 22, 18, 14, 10, 6, 2], " +
"Player 3=[49, 45, 41, 37, 33, 29, 25, 21, 17, 13, 9, 5, 1], " +
"Player 4=[48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0]}")

我写的逻辑是这样的:

Map<String, List<Card>> myMap = new HashMap<>();
for(int i=0; i<players; i++){
    myMap.put("Player " + i, ///here i don't know how to put these values;
}

有什么建议如何根据任务将这些列表放入地图中?

【问题讨论】:

  • 打乱列表,将其分成四个大小相等、分离的子列表,为每个玩家分配一个子列表。
  • 输出看起来是连续的,就像一个分布。我不认为他们在寻找洗牌。
  • 到底是什么问题?如何在地图中添加列表或如何为每个玩家生成列表? (或两者兼而有之)

标签: java list dictionary arraylist


【解决方案1】:

由于无法弄清楚到底需要什么,也许这会有所帮助。

public class TestAddMap {

    public static void main(String[] args)
    {
        Map<String, List<Integer>> map = new HashMap<>();
        int numberOfPlayers = 4;
        
        for(int i=1;i<=numberOfPlayers;i++)
        {
            Player p=new Player("player_"+i);
            //construct player_n list
            for(int j=1;j<=52;j++)
            {
                if((j-i)%numberOfPlayers==0)
                {
                    p.getList().add(j);
                }
                //even if the result is fine it's better to add line after for_loop
                //being here is just update old entries
                map.put(p.name,p.list);
            }
            //add entry when list for player_n is fully populated
            //map.put(p.name,p.list);
        }
        
        map.forEach((k,v)->System.out.println(k+":"+v));
        
    }
    static class Player
    {
        String name;
        List<Integer> list=new ArrayList<Integer>();
        Player(String name)
        {
            this.name=name;
        }
        
        public List<Integer> getList()
        {
            return list;
        }
        
        public String toString()
        {
            return list.stream().
                        map(i->String.valueOf(i)).
                        collect(Collectors.joining(","));
        }
    }
}

输出:

numberOfPlayers = 4
player_1:[1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49]
player_4:[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52]
player_3:[3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51]
player_2:[2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50]

numberOfPlayers = 3
player_1:[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52]
player_3:[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51]
player_2:[2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50]

etc.

注意: 构造 player_n 列表可以用

进行优化
//loop will skip directly values which not belong to player_n 
for(int j=i;j<=52;j=j+numberOfPlayers)
{
    p.getList().add(j); 
}

【讨论】:

    【解决方案2】:

    这是一种方法。

    • 通过IntStream 生成 1 到 n 个玩家
    • 使用当前玩家#,生成一个地图条目来保存玩家和列表。
      • 列表是通过从52-player #迭代构造的,以# of players的数量为增量,再次使用IntStream
      • 然后将号码映射到Card 实例并存储在列表中。
    • 然后将玩家编号和列表转移到LinkedHashMap(我选择了地图类型以直观地显示添加值的顺序)。

    卡片类

    class Card {
        public int v;
        public Card(int v) {
            this.v = v;
        }
        @Override
        public String toString() {
            return v+"";
        }
    }
    

    主要代码

    
    int nPlayers = 4;
    Map<String, List<Card>> map = IntStream.rangeClosed(1, nPlayers)
            .mapToObj(
                    player -> new AbstractMap.SimpleEntry<String, List<Card>>(
                            "Player" +player,
                            IntStream.iterate(52 - player,
                                    i -> i >= 0, i -> i -= nPlayers)
                                    .mapToObj(Card::new)
                                    .toList()))
            .collect(Collectors.toMap(Entry::getKey,
                    Entry::getValue,
                    (a,b)->a,             // may be removed if 
                    LinkedHashMap::new)); // map type not relevant.
    
    map.entrySet().forEach(System.out::println);
    

    对于四个玩家,打印

    Player1=[51, 47, 43, 39, 35, 31, 27, 23, 19, 15, 11, 7, 3]
    Player2=[50, 46, 42, 38, 34, 30, 26, 22, 18, 14, 10, 6, 2]
    Player3=[49, 45, 41, 37, 33, 29, 25, 21, 17, 13, 9, 5, 1]
    Player4=[48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0]
    

    在这里编写流方法是一种更传统的方法,可能更有效且更易于理解。

    Map<String, List<Card>> map2 = new LinkedHashMap<>();
    for (int i = 1; i <= nPlayers; i++) {
        List<Card> list = new ArrayList<>();
        for (int c = 52-i; c >= 0; c -= nPlayers) {
            list.add(new Card(c));
        }
        map2.put("Player" + i, list);
    }
    

    【讨论】:

      【解决方案3】:

      我认为您想在玩家之间“分配”卡片。你可以为每个玩家使用这样的东西:

      first player 51 - 4 * i
      second player 50 - 4 * i
      third player 49 - 4 * i
      fourth player 48 - 4 * i
      

      i 的范围是 0 到 12(含)。

      【讨论】:

      • 是的,但是你怎么能把这些值放在地图上呢?作为列表?但是当任务要求不是 4 个而是 5、6、7、.8 个玩家时会发生什么,你会为他们创建新列表还是什么?
      猜你喜欢
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多