You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅地用List中的动物元素随机填充二维Cell数组?

问题描述

我有一个Cell类型的二维数组:public static Cell[][] island = new Cell[3][3];,每个Cell包含x、y坐标以及栖息其中的动物列表。我需要用public static List<Alive> allanimals = new ArrayList<>();列表中的动物随机填充这个数组。

我写了列表生成与填充的代码,但最终得到大量空单元格,而且觉得animalsInCell = allanimals.subList(initialcount, initialcount + randomdata);这段实现不够优雅。请问如何正确用allanimals里的元素填充Island数组?

我的Cell类定义如下:

@Data
@AllArgsConstructor
public class Cell extends Thread{
    private int x;
    private int y;
    public List<Alive> animals;
    // method run()
}

原填充代码:

public static void generateIsland() {
    for (int i = 0; i < 10; i++) {
        int random = (int) (Math.random() * 100);
        if (random < 50) {
            allanimals.add(new Bear(500,5,0,0));
        } else {
            allanimals.add(new Sheep(70,0,0));
        }
    }
    System.out.println("Randomly create all animals list" + allanimals);
    int initialcount = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            try {
                int randomdata = r.nextInt(0, allanimals.size() );

                List<Alive> animalsInCell = new ArrayList<>();

                animalsInCell = allanimals.subList(initialcount, initialcount + randomdata);

                initialcount += randomdata;

                island[i][j] = new Cell(i, j, animalsInCell);
            } catch (Exception e) {
                island[i][j] = new Cell(i, j, new ArrayList<Alive>());
            }
        }
    }
}

问题分析
  1. 原代码中randomdata取值范围是0到allanimals.size(),极易出现initialcount + randomdata超出列表长度的情况,触发异常后进入catch块生成空单元格。
  2. subList返回的是原列表的视图,并非独立新列表,后续修改allanimals会同步影响单元格内的动物列表,不符合业务隔离需求。
  3. 分配逻辑无约束,可能前几个单元格就耗尽所有动物,导致后续单元格全部为空。

优化方案

方案一:随机分配单只动物到单元格(简单直观)

每只动物随机分配到一个单元格,逻辑简单且避免空单元格(只要动物数量>0):

import java.util.Random;

public static void generateIsland() {
    Random random = new Random();
    // 生成动物列表
    for (int i = 0; i < 10; i++) {
        if (random.nextBoolean()) { // 50%概率生成Bear,50%生成Sheep
            allanimals.add(new Bear(500, 5, 0, 0));
        } else {
            allanimals.add(new Sheep(70, 0, 0));
        }
    }
    System.out.println("Randomly create all animals list: " + allanimals);

    // 先初始化所有单元格的空动物列表
    for (int i = 0; i < island.length; i++) {
        for (int j = 0; j < island[i].length; j++) {
            island[i][j] = new Cell(i, j, new ArrayList<>());
        }
    }

    // 随机分配每只动物到某个单元格
    for (Alive animal : allanimals) {
        int x = random.nextInt(island.length);
        int y = random.nextInt(island[0].length);
        island[x][y].getAnimals().add(animal);
    }
}

方案二:随机划分动物到所有单元格(无动物剩余)

确保所有动物都被分配,且每个单元格的动物数量随机分布:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public static void generateIsland() {
    Random random = new Random();
    // 生成动物列表
    for (int i = 0; i < 10; i++) {
        if (random.nextBoolean()) {
            allanimals.add(new Bear(500, 5, 0, 0));
        } else {
            allanimals.add(new Sheep(70, 0, 0));
        }
    }
    System.out.println("Randomly create all animals list: " + allanimals);

    // 打乱动物列表,让分配更随机
    Collections.shuffle(allanimals);

    int totalCells = island.length * island[0].length;
    int animalIndex = 0;

    // 遍历所有单元格分配动物
    for (int i = 0; i < island.length; i++) {
        for (int j = 0; j < island[i].length; j++) {
            // 最后一个单元格拿走剩余所有动物
            if (i == island.length - 1 && j == island[i].length - 1) {
                List<Alive> remainingAnimals = new ArrayList<>(allanimals.subList(animalIndex, allanimals.size()));
                island[i][j] = new Cell(i, j, remainingAnimals);
            } else {
                // 计算剩余单元格数量,避免提前耗尽动物
                int remainingCells = totalCells - (i * island[i].length + j + 1);
                int maxAssign = allanimals.size() - animalIndex - remainingCells;
                int assignCount = maxAssign > 0 ? random.nextInt(1, maxAssign + 1) : 0;

                // 用新ArrayList包装subList结果,脱离原列表关联
                List<Alive> cellAnimals = new ArrayList<>(allanimals.subList(animalIndex, animalIndex + assignCount));
                island[i][j] = new Cell(i, j, cellAnimals);
                animalIndex += assignCount;
            }
        }
    }
}

关键注意点
  • 永远不要直接将subList的返回值作为Cell的动物列表,必须用new ArrayList<>(subListResult)包装,避免和原列表产生关联。
  • 确保Random实例的线程安全性,建议在方法内声明或作为类成员变量初始化。
  • 若要完全避免空单元格,可调整方案二的assignCount最小值为1,同时保证动物数量≥单元格总数(9只)。

内容的提问来源于stack exchange,提问作者SoN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:16:20