如何从 ArrayList 中获取某些值并将它们放入地图中

How to get certain values from ArrayList and put them in a map

我有一个程序,其中有 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;
}

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

我想你想'distribute'玩家之间的卡片。你可以为每个玩家使用这样的东西:

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

其中 i 从 0 到 12(含)。

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

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

这是一种方法。

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

卡片class

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