两种方法返回集合中所有和特定值之和的总和

时间:2014-04-24 13:10:29

标签: java design-patterns

想象一下如下所示的课程。我必须编写一些代码,这些代码可以汇总集合的所有值以及满足给定标准的所有值。

class MyClass {
    private String name;
    private int value;
}

我当前的代码看起来像这样。以下功能是否有更优雅的设计模式?

public static int sumFilter(Collection<MyClass> collection, String filter) {
   int result = 0;
   for (MyClass myClass : collection) {
       if (filter == null || filter.equals(myClass.getName()) {
           result += myClass.getValue();
       }
   }
   return result;
}

public static int sumAll(Collection<MyClass> collection) {
   return sumFilter(collection, null);
}

2 个答案:

答案 0 :(得分:2)

如果您使用的是基于流的Java 8,那么还有更优雅的解决方案:

List<MyObj> collection = ...; //initialization;

int sum = 0;
collection.stream()
    .filter(obj -> filter != null ? obj.getValue().equals(filter) : true)
    .mapToInt(obj -> obj.getIntValue()).sum();

答案 1 :(得分:2)

改进现有方法:

通过使用Filter作为接口(并且必须添加更多代码),您可以为过滤规则添加更多灵活性 - 非常类似于在使用custom {{Collections.sort方法调用Comparator方法时应用不同的比较规则1}},例如:

interface Filter<T> {
    boolean include(T item);

    public final static Filter<Object> INCLUDE_ALL = new Filter<Object>() {
        @Override
        public boolean include(Object item) {
            return true; /* includes everything unconditionally */
        }
    };
}



public static int sumFilter(Collection<MyClass> collection, 
        Filter<? super MyClass> filter) {

    int result = 0;
    if (filter == null) {
        filter = Filter.INCLUDE_ALL;
    }
    for (MyClass item : collection) {
        if (filter.include(item)) {
            result += item.value;
        }
    }
    return result;
 }

public static int sumAll(Collection<MyClass> collection) {
    return sumFilter(collection, Filter.INCLUDE_ALL);
}

然后你可以拥有更复杂规则的自定义过滤器(而不仅仅是你的例子中的String.equals),例如匹配正则表达式:

    new Filter<MyClass>() {

        @Override
        public boolean include(MyClass item) {
            return item.getName().matches("some regex");
        }
    };