如何在创建Flat对象时动态扩容Block类的flats数组?
解决方案:创建Flat时自动添加到Block的flats数组
嘿,我来帮你搞定这个需求!你想要每次新建Flat对象时,自动把它加入对应Block的flats数组里,刚好你的代码里Flat是Block的非静态内部类——这个特性就是关键,因为每个非静态内部类的实例都必须依附于一个外部类(Block)的实例存在,我们可以利用这一点来关联两者。
核心思路
- 在Block类里新增一个方法,专门负责把Flat实例添加到flats数组中(封装扩容逻辑,符合代码规范)
- 在Flat的构造方法里,通过
Block.this获取当前Flat所属的Block实例,然后调用这个新增的添加方法,把自己加进去
修改后的完整代码(基于原数组实现)
public class Block { public Block() { super(); flats = new Flat[0]; } Flat[] flats; // 新增:封装Flat的添加逻辑,负责数组扩容 private void addFlat(Flat flat) { // 创建长度+1的新数组(Java数组不可变,必须新建) Flat[] newFlats = new Flat[flats.length + 1]; // 复制原数组的所有元素到新数组 System.arraycopy(flats, 0, newFlats, 0, flats.length); // 把新Flat放到数组最后一位 newFlats[flats.length] = flat; // 替换原数组引用 flats = newFlats; } class Flat { Room[] rooms; class Room { private int width; private int height; private int numWindow; public Room(int w, int h, int n) { super(); this.width = w; this.height = h; this.numWindow = n; } @Override public String toString() { return width + "/" + height + "/" + numWindow; } } public Flat() { super(); rooms = new Room[0]; // 关键:创建Flat时,主动让所属Block把自己加进数组 Block.this.addFlat(this); } } }
优化方案:改用ArrayList替代数组
如果你觉得每次扩容数组太麻烦(尤其是频繁创建Flat时,数组扩容会有性能开销),可以把Flat[] flats换成List<Flat>,这样添加操作会简单很多:
public class Block { public Block() { super(); flats = new ArrayList<>(); // 初始化空列表 } List<Flat> flats; // 替换数组为ArrayList private void addFlat(Flat flat) { flats.add(flat); // 直接添加,无需手动扩容 } // Flat和Room类的代码完全不变,构造里还是调用Block.this.addFlat(this) }
测试验证
你可以用这段代码测试效果:
public class TestBlock { public static void main(String[] args) { Block myBlock = new Block(); // 创建3个Flat实例 myBlock.new Flat(); myBlock.new Flat(); myBlock.new Flat(); // 打印结果:如果用数组,输出3;用ArrayList的话调用size()输出3 System.out.println(myBlock.flats.length); } }
注意事项
- 非静态内部类不能脱离Block实例创建,必须用
blockInstance.new Flat()的方式创建Flat,否则会编译错误——这也刚好保证了每个Flat都有对应的Block可以关联,不会出现找不到Block的情况。 - 把添加逻辑封装到Block的
addFlat方法里,而不是直接在Flat构造里操作数组,这是为了遵循封装原则,以后如果要修改添加逻辑(比如加校验、换存储结构),只需要改Block里的方法就行,不用动Flat的代码。
内容的提问来源于stack exchange,提问作者Haluk
相关产品推荐
相关产品推荐

