返回集合或单个值的方法

时间:2017-06-18 11:17:05

标签: java collections

我有一个具有各种属性的类,我想在它们周围编写一个包装器方法,以便更容易地循环它们。

某些属性会返回集合值,有些属性为单个值。我正在寻找最佳方法。

我的第一种方法是让包装器方法返回属性getter返回的内容。

public class Test {

    public Object getValue(String propName) {
        if ("attr1".equals(propName)) return getAttribute1();
        else if ("attr2".equals(propName)) return getAttribute2();
        else return null;
    }

    public List<String> getAttribute1() {
        return Arrays.asList("Hello","World");
    }

    public String getAttribute2() {
        return "Goodbye";
    }

    public static void main(String[] args) {

        final Test test=new Test();

        Stream.of("attr1","attr2")
                .forEach(p-> {
                    Object o=test.getValue(p);
                    if (o instanceof Collection) {
                        ((Collection) o).forEach(v->System.out.println(v));
                    }
                    else {
                        System.out.println(o);
                    }
                });
    }

}

这种方法的不足之处在于调用者必须自己测试结果是否是集合。

对于调用者来说无缝的其他方法是始终返回一个集合,即。包装器函数将单个值包装到Collection中。这里是一个HashSet,但我们可以设想一个特殊的,最小的1个元素列表。

public class TestAlt {

    public Collection getValue(String propName) {
        if ("attr1".equals(propName))
            return getAttribute1();
        else if ("attr2".equals(propName)) {
            Set s = new HashSet();
            s.add(getAttribute2());
            return s;
        }
        else
            return null;
    }

    public List<String> getAttribute1() {
        return Arrays.asList("Hello", "World");
    }

    public String getAttribute2() {
        return "Goodbye";
    }

    public static void main(String[] args) {

        final TestAlt test = new TestAlt();

        Stream.of("attr1", "attr2")
                .forEach(p -> {
                    test.getValue(p).forEach(v -> System.out.println(v));
                });
    }

性能方面,设计明智,......您对这些方法的看法是什么?你有更好的想法吗?

2 个答案:

答案 0 :(得分:0)

好吧,您可以将要对每个属性执行的操作传递给对象,然后让对象决定如何处理它。 E.g:

在课堂测试中:

public void forEachAttribute(String propName, Handler h) {
    if ("attr1".equals(propName))
        h.handle(getAttribute1());
    else if ("attr2".equals(propName)) {
        getAttribute2().forEach(o -> h.handle(o))
    }
}

一个功能为Handler的课程handle(String s)就是你要做的。

如果您无法修改Test,也可以将功能移到Test

之外
public void forEachTestAttribute(Test t, String propName, Handler h)...

性能方面:这将删除if子句

设计明智:这会移除一个演员表,但会创建更多类。

*编辑:它还维护类型安全性,如果有多种属性(Stringint等),您可以添加更多handle - 函数,仍然保持类型安全。

答案 1 :(得分:0)

关于设计,我会将您的代码重写为:

<强> TestAlt.java

import java.util.*;
import java.util.stream.Stream;

public class TestAlt {

    private Map<String, AttributeProcessor> map = AttributeMapFactory.createMap();

    public Collection getValue(String propName) {
        return Optional
            .ofNullable(map.get(propName))
            .map(AttributeProcessor::getAttribute)
            .orElse(Arrays.asList("default")); //to avoid unexpected NPE's 
    }


    public static void main(String[] args) {

        final TestAlt test = new TestAlt();

        Stream.of("attr1", "attr2")
            .forEach(p -> test.getValue(p).forEach(v -> System.out.println(v)));
    }
}

<强> AttributeMapFactory.java

import java.util.HashMap;
import java.util.Map;

public class AttributeMapFactory {

    public static Map<String, AttributeProcessor> createMap() {
        Map<String, AttributeProcessor> map = new HashMap<>();
        map.put("attr1", new HiAttributeProcessor());
        map.put("attr2", new ByeAttributeProcessor());
        return map;
    }
}

<强> AttributeProcessor.java

import java.util.Collection;

public interface AttributeProcessor {

    Collection<String> getAttribute();
}

<强> HiAttributeProcessor.java

import java.util.Arrays;
import java.util.Collection;

public class HiAttributeProcessor implements AttributeProcessor{

    @Override
    public Collection<String> getAttribute() {
        return Arrays.asList("Hello", "World");
    }
}

<强> ByeAttributeProcessor.java

import java.util.Arrays;
import java.util.Collection;

public class ByeAttributeProcessor implements AttributeProcessor{

    @Override
    public Collection<String> getAttribute() {
        return Arrays.asList("Goodbye");
    }
}

重点是你使用map和动态调度来摆脱if-else语句。

这种方法的主要优点是您的代码可以更灵活地进行进一步的更改。在这个小程序的情况下,它并不重要,并且是一种矫枉过正。但是,如果我们谈论大型企业应用程序,那么是的,它变得至关重要。