对于一组Power 对象,使用Set < Power >
如果您想跟踪一组Power 对象,请使用Set 类。不需要可变参数,只需传递一个Set 对象。
为了简单起见,让我们使用 Java 16 中的 Record 特性。编译器隐式创建构造函数、getter、equals & hashCode 和 toString。当类的主要目的是透明和不可变地携带数据时,记录是合适的。使用记录使这个示例代码更短。
package work.basil.example.Game;
import java.util.Set;
public record GameCharacter (String name, Set <Power> powers)
{
}
对于不可修改的Set,使用Set.of 方法。
package work.basil.example.Game;
public record Power(String description)
{
}
package work.basil.example.Game;
import java.util.Set;
public class App
{
public static void main ( String[] args )
{
App app = new App();
app.demo();
}
private void demo ( )
{
GameCharacter susan = new GameCharacter(
"Susan" ,
Set.of(
new Power( "invisibility" ) ,
new Power( "force field" )
)
);
GameCharacter ben = new GameCharacter(
"Ben" ,
Set.of(
new Power( "physical strength" ) ,
new Power( "rock-like hide" )
)
);
System.out.println( "susan = " + susan );
System.out.println( "ben = " + ben );
}
}
运行时:
susan = GameCharacter[name=Susan, powers=[Power[description=force field], Power[description=invisibility]]]
ben = GameCharacter[name=Ben, powers=[Power[description=rock-like hide], Power[description=physical strength]]]
如果您要定义常规类而不是record,您将在GameCharacter 类上定义两个成员字段:String 用于名称,Set < Power > powers 用于Power 对象的集合。你会添加一个构造函数,为这两个字段提供两个参数。
package work.basil.example.Game;
import java.util.Objects;
import java.util.Set;
public final class GameCharacter
{
// Member fields
private final String name;
private final Set < Power > powers;
// Constructor
public GameCharacter ( String name , Set < Power > powers )
{
this.name = name;
this.powers = powers;
}
public String name ( ) { return name; }
public Set < Power > powers ( ) { return powers; }
@Override
public boolean equals ( Object obj )
{
if ( obj == this ) return true;
if ( obj == null || obj.getClass() != this.getClass() ) return false;
var that = ( GameCharacter ) obj;
return Objects.equals( this.name , that.name ) &&
Objects.equals( this.powers , that.powers );
}
@Override
public int hashCode ( )
{
return Objects.hash( name , powers );
}
@Override
public String toString ( )
{
return "GameCharacter[" +
"name=" + name + ", " +
"powers=" + powers + ']';
}
}
可变参数
现在我们可以回到您的具体问题:如何在您的构造函数中处理可变参数。
这里我们为上面看到的类添加了第二个构造函数。第二个采用Power 类型的可变参数。
可变参数作为Power 对象的数组到达。我们可以使用 for-each 语法循环该数组的元素。我们将每个元素添加到我们选择的新 Set 实现中,在本例中为 HashSet 类。
public GameCharacter ( String name , Power... powers )
{
this.name = name;
Set<Power> s = new HashSet <>(); // New empty `Set` implementation.
for ( Power power : powers ) // `powers` is the varargs array of `Power` objects.
{
s.add(power); // Add each element of array, each `Power` object, to our `Set` collection.
}
this.powers = s;
}
为了使用这个构造函数,我们调整了 App 类以放弃对 Set.of 的调用。
package work.basil.example.Game;
import java.util.Set;
public class App
{
public static void main ( String[] args )
{
App app = new App();
app.demo();
}
private void demo ( )
{
GameCharacter susan = new GameCharacter(
"Susan" ,
new Power( "invisibility" ) ,
new Power( "force field" )
);
GameCharacter ben = new GameCharacter(
"Ben" ,
new Power( "physical strength" ) ,
new Power( "rock-like hide" )
);
System.out.println( "susan = " + susan );
System.out.println( "ben = " + ben );
}
}
这里是我们修改后的GameCharacter 的整个类的源代码,现在提供了两个构造函数。
package work.basil.example.Game;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public final class GameCharacter
{
// Member fields
private final String name;
private final Set < Power > powers;
// Constructors
// First constructor
public GameCharacter ( String name , Set < Power > powers )
{
this.name = name;
this.powers = powers;
}
// Second constructor
public GameCharacter ( String name , Power... powers )
{
this.name = name;
Set<Power> s = new HashSet <>();
for ( Power power : powers )
{
s.add(power);
}
this.powers = s;
}
// Getters
public String name ( ) { return name; }
public Set < Power > powers ( ) { return powers; }
// `Object` overrides
@Override
public boolean equals ( Object obj )
{
if ( obj == this ) return true;
if ( obj == null || obj.getClass() != this.getClass() ) return false;
var that = ( GameCharacter ) obj;
return Objects.equals( this.name , that.name ) &&
Objects.equals( this.powers , that.powers );
}
@Override
public int hashCode ( )
{
return Objects.hash( name , powers );
}
@Override
public String toString ( )
{
return "GameCharacter[" +
"name=" + name + ", " +
"powers=" + powers + ']';
}
}
提示:如果您希望您的成员字段 powers 是一个不可修改的集合,您可以将第二个构造函数简化为:
// Second constructor
public GameCharacter ( String name , Power... powers )
{
this.name = name;
this.powers = Set.of( powers ) ; // Make an unmodifiable set from the varargs array.
}