表示带有Java类分数的核对表

时间:2014-07-22 11:08:45

标签: java oop architecture

我有一个项目清单,表示为Java类。

E.g。

public class CheckList {
    private boolean firstItem;
    private boolean secondItem;
    private boolean thirdItem;

    public boolean isFirstItem() { return firstItem; }
    public void setFirstItem(boolean firstItem) { this.firstItem = firstItem; }

    public boolean isSecondItem() { return secondItem; }
    public void setSecondItem(boolean secondItem) { this.secondItem = secondItem; }

    public boolean isThirdItem() { return thirdItem; }
    public void setThirdItem(boolean thirdItem) { this.thirdItem = thirdItem; }
}

现在,我想“计算”检查清单中有多少项目的分数(百分比)。我天真的做法是采用以下方法。

private static final int NR_OF_ITEMS = 3;

public double getScore() {
    double score = 0;
    if (firstItem) { score += 1; }
    if (secondItem) { score += 1; }
    if (thirdItem) { score += 1; }

    return score / NR_OF_ITEMS;
}

然而,这在某种程度上是不切实际的,似乎很奇怪(特别是如果核对表变得更长)。另一种方法可能是拥有一个可以迭代的项目列表,但这确实意味着不能轻易限制项目并且它也有缺陷。

用Java代表清单可能是一个很好的解决方案吗?谢谢你的想法。

1 个答案:

答案 0 :(得分:1)

我采用你的第二种方法,即使用一个项目列表。如果将列表包装在另一个类中并在插入时检查列表的大小,则限制项目的数量将很容易。

示例:

class Item {
  boolean checked;
  String name;
}

class CheckList {
  private final int maxItemsAllowed;
  private final List<Item> items;

  public CheckList( int maxItems ) {
    maxItemsAllowed = maxItems;
    items = new ArrayList<>( maxItemsAllowed  );
  }



  public void addItem( Item i ) {
    if( items.size() >= maxItemsAllowed ) {
      throw new IllegalArgumentException("Maximum no. of allowed items (" + maxItemsAllowed + ") exeeded");
    }

    items.add( i );
  }
}

还有什么&#34;缺陷&#34;你在想什么?

<强>更新

为了限制可能的项目数量,您可以使Item成为枚举和/或不提供操作主题列表的公共方法。

为了处理重复项,请使用Set<Item>,并根据您希望如何控制项目顺序TreeSetComparatorLinkedHashSet使用修改后的尺寸检查。

另一种方法可能是使用Map<Item, Boolean>并将标志存储在项目之外。

示例:

 enum Item {
   ITEM_1("Item no. 1"),
   ITEM_2("A second item");     

   private final String name;

   private Item( String name ) {
     this.name = name;
   } 

   public String getName() { return name; }
 }

 class CheckList {
   private final int maxItemsAllowed;
   private final Map<Item, Boolean> items; //make this a TreeMap or LinkedHashMap

   //Constructor and other methods omitted for clarity 

   public void check(Item item, boolean checked ) {
     if( !items.containsKey( item ) ) { 
       throw new IllegalArgumentException("unknown item"); 
     }
     items.put(item, checked); //note the autoboxing here
   }

   public double getScore() {
     int countChecked = 0;
     int countTotal = 0;  //see explanation below
     for( Boolean b : items.values() ) {
       if( Boolean.TRUE.equals( b ) {
         countChecked++;
       }
       countTotal++;
     }

     return (double)countChecked/countTotal;
   }
 }

那么为什么countTotal方法中有getScore()?由于地图允许使用空值,具体取决于您的实施和清单的使用情况,因此可能列表中的项目的标志(值)可能为空。如果是这种情况,并且null并不意味着false,您只需检查b != null,只有增加countTotal,如果这是真的,即它将是数字非空项目。