所以我正在为我的在线AP计算机科学课做一个项目并且遇到了一个问题...这是我给予构建的原始类定义(剥离了与我的问题无关的代码):
注意:Bin类的构造函数接受一个参数String。字符串代表Bin的名称。
import java.util.*;
public class Warehouse
{
// Declare instance variables here
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( 5 );
// Code that will start the warehouse
// off with 5 empty bins
}
public void addBin()
{
myBins.add( new Bin( "B" + myBins.size() ) );
}
}
我的工作是用实际代码实现替换注释掉的区域。虽然实例变量的声明非常简单,但我更倾向于实现第二条评论中提到的代码的最佳方法。
简而言之,哪个是完成上述构造函数的最佳方法?
解决方案A:
private int myBinMax;
private ArrayList<MusicMedia> myCatalog;
private ArrayList<Bin> myBins;
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( 5 );
for(int i = 0; i < 5; i++)
{
myBins.add( new Bin( "B" + myBins.size() ) );
}
}
解决方案B:
private int myBinMax;
private ArrayList<MusicMedia> myCatalog;
private ArrayList<Bin> myBins;
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( 5 );
for(int i = 0; i < 5; i++)
{
addBin(); // <= Is this considered bad practice?
}
}
解决方案C:
// Some magical wizard code I would have never thought of. XD
提前致谢!
答案 0 :(得分:2)
你能使用Java 8吗?
final List<Bin> bins = IntStream.range(0, 5).
mapToObj(i -> new Bin("Bin" + i)).
collect(Collectors.toCollection(ArrayList::new));
否则,您的解决方案看起来都很好。我希望B
,因为您已经有一个addBin
方法,但有一个警告。您必须addBin
final
,因为它是public
方法。您应该只从构造函数中调用private
或final
方法,否则您可能会冒某人(可能是您)在子类中重写该方法,然后在初始化子类之前从超类构造函数调用子类方法。
答案 1 :(得分:1)
尝试在代码中使用常量而不是幻数:)
import java.util.*;
public class Warehouse
{
// Declare instance variables here
private static final int INITIAL_BINS = 5;
private static final String DEFAULT_BINNAME = "DefaultBin_";
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( INITIAL_BINS );
for(int i = 0; i < INITIAL_BINS; i++)
{
myBins.add( new Bin( DEFAULT_BINNAME + i ) );
//addBin();// This is fine too depends on how flexible you want naming to be:)
}
}
public void addBin()
{
myBins.add( new Bin( "B" + myBins.size() ) );
}
}
答案 2 :(得分:1)
虽然我同意大多数已经说过的内容,但java 8函数编程风格的单行程非常性感。应避免使用魔术数字/字符串。如果你的课程没有超越功能风格,为什么不将整个for循环移动到它自己的功能中呢?通常,构造函数应该做的唯一事情就是初始化对象的状态。为了明确这一点,我尝试保持每个成员变量一行,并且一行只不过是一个初始化语句。 IMO方法(可以引用对象的当前状态)不应该从构造函数中调用,因为您的对象尚未创建。如果要添加函数来帮助初始化对象,请随意执行此操作但保持静态,以便明确函数的意图(不是指对象的状态)。
...
private static final int INITIAL_BIN_COUNT = 5;
private static final String BIN_PREFIX = "B";
private final List<Bin> myBins;
public Warehouse(...) {
....
myBins = initMyBins();
}
private static List<Bin> initMyBins() {
final List<Bin> result = new ArrayList<Bin>(INITIAL_BIN_COUNT);
for(int i = 0; i < INITIAL_BIN_COUNT; i++) {
result.add(new Bin(BIN_PREFIX+i));
}
return result;
}
...
P.S。还有一些注意事项,通常很好的做法是编写接口类型而不是具体的类类型(可能你还没有覆盖接口,但这就是我将ArrayList更改为List所做的。 / p>