我是Java的新手,我对如何格式化数组以保存对象感到非常困惑,特别是具有多种数据类型。我正在尝试制作一个名为myMonsters的数组,该数组基本上包含一堆其他怪物,这是一个字符串和一个整数。1,我真的不明白如何将对象放入数组中。2,我不明白为什么数组在一个类名下而不是另一个类名下。 我的意思是-->
private Monster[] myMonsters;
private int s;
public Monsters(int size)
{
s = size;
myMonsters = new Monster[s];
}
public void add(int spot, Monsters m)
{
myMonsters[spot] = m;
}
这将创建保存怪物对象的数组。我不明白为什么要在怪物下创建数组。在持有怪物对象的怪物类下创建它不是更有意义吗?
private int weight;
private int height;
private int age;
public Monster( int a, int h, int w )
{
age = a;
height = h;
weight = w;
}
当然,这会创建对象。 我可以说这个问题的格式有多差,但你还能帮我解决这个问题吗?
类是一个模板,就像制作饼干的千篇一律。一个类没有内容,就像一个千篇一律的人没有饼干面团一样。
千篇一律的存在只是为了制作美味的饼干。类的存在只是为了创建有用的对象(也称为实例)。对象里面有内容,就像饼干里面有面团一样。
Monster
是制作各种怪物的类,千篇一律的。
在 Java 16 及更高版本中,我们可以更简要地将类定义为记录。编译器隐式创建构造函数、getter、equals
&hashCode
和toString
。
package work.basil.example.animalkingdom.cookies;
public record Monster(String name , int weight)
{
}
作为传统类,这将是:
package work.basil.example.animalkingdom.cookies;
import java.util.Objects;
public final class Monster
{
private final String name;
private final int weight;
public Monster ( String name , int weight )
{
this.name = name;
this.weight = weight;
}
public String name ( ) { return name; }
public int weight ( ) { return weight; }
@Override
public boolean equals ( Object obj )
{
if ( obj == this ) return true;
if ( obj == null || obj.getClass() != this.getClass() ) return false;
var that = ( Monster ) obj;
return Objects.equals( this.name , that.name ) &&
this.weight == that.weight;
}
@Override
public int hashCode ( )
{
return Objects.hash( name , weight );
}
@Override
public String toString ( )
{
return "Monster[" +
"name=" + name + ", " +
"weight=" + weight + ']';
}
}
让我们用这个千篇一律的切割器切一些饼干。我们想代表 3 个怪物,每个怪物都有不同的名字和不同的重量。
Monster x = new Monster( "Alice" , 42 );
Monster y = new Monster( "Bob" , 77 );
Monster z = new Monster( "Carol" , 58 );
在那里,我们有三个独立的对象,每个对象都来自同一个Monster
类。我们目前正在分别处理 3 个怪物,每个怪物都分配给单独的变量。
如果我们想按照特定的顺序一起追踪这些怪物,我们不需要你的Monsters
类。只需使用数组。
假设我们希望它们按重量组织在一起。
Monster[] monstersByWeight = new Monster[ 3 ];
monstersByWeight[ 0 ] = x;
monstersByWeight[ 1 ] = z;
monstersByWeight[ 2 ] = y;
Monster[]
说我们希望这个名为monstersByWeight
的变量保存一个保存Monster
对象的数组。new Monster[ 3 ]
创建这样一个数组,一个有三个空插槽的数组。=
将三个空插槽的数组放入名为monstersByWeight
的变量中,以便我们稍后使用它。
将该阵列转储到控制台进行检查。
String output = Arrays.toString( monstersByWeight );
System.out.println( "output = " + output );
输出 = [怪物[名称=爱丽丝,重量=42],怪物[名称=卡罗尔,重量=58],怪物[名称=鲍勃,重量=77]]
你说:
。保存对象,特别是具有多种数据类型的对象
这里只涉及一种数据类型:Monster
。我们只有Monster
对象要跟踪。因此,名为monstersByWeight
的数组的数据类型为Monster
。
如果我们想添加另一个Monster
对象:
Monster david = new Monster( "David" , 63 ) ;
。对于我们的阵列,我们需要打开一个插槽。使用数组,这是繁琐的编程。我们可能会创建另一个数组,将元素从旧数组移动到新数组,同时跳过我们要为新Monster
保持开放的插槽。编写代码不好玩。
幸运的是,该代码已经编写完毕。我们可以使用类ArrayList
.实现List
接口的此类。ArrayList
可以为我们完成所有元素插入工作。
List< Monster > monstersByWeight = new ArrayList<>() ;
List< Monster > monstersByWeight
说我们想要一个包含Monster
对象的列表。new ArrayList<>()
实例化此类默认大小的列表。
接下来,我们添加Monster
对象。
monstersByWeight.add( x ) ;
monstersByWeight.add( z ) ;
monstersByWeight.add( y ) ;
转储到控制台。
System.out.println( monstersByWeight ) ;
[怪物[名称=爱丽丝,体重=42],怪物[名称=卡罗尔,体重=58],怪物[名称=鲍勃,体重=77]]
稍后我们可以插入名为David
的新Monster
对象,分配给名为david
的变量。这个新怪物的体重为63,属于名为Bob
的怪物,但属于名为Carol
的怪物。与数组一样,List
接口使用烦人的从零开始计数而不是序数计数。要指定第 3 个元素,我们说2
(正如我所说,很烦人)。
monstersByWeight.add( 2 , david ) ;
转储到控制台。
System.out.println( monstersByWeight ) ;
[怪物[名称=爱丽丝,体重=42],怪物[名称=卡罗尔,体重=58],怪物[名称=大卫,体重=63],怪物[名称=鲍勃,体重=77]]
你问:
这将创建保存怪物对象的数组。我不明白为什么要在怪物下创建数组。在持有怪物对象的怪物类下创建它不是更有意义吗?
不,您不希望将Monster
对象的集合存储在Monster
类中。Monster
类的工作是为表示任何一个现实世界怪物的任何一个Monster
对象(实例)定义状态(数据)和行为(方法)。
您需要一个单独的类来跟踪一堆Monster
对象。在这个答案中,我们使用了我们命名为monstersByWeight
的ArrayList
类的实例来跟踪我们的怪物群。如果你想自己做所有的数组重新排列,你也可以编写自己的MonsterList
类,作为练习。但是对于实际工作,请使用ArrayList
.
这里工作的主要内容称为关注点分离。ArrayList
阶级对成为Monster
意味着什么一无所知。Monster
类不知道如何将对象组合在一起Monster
。遵循此原则可以获得干净、组织良好的代码,更易于阅读、理解和维护。