更好的设计模式?

时间:2016-04-26 20:17:16

标签: java design-patterns javabeans

我的myArrayList已经有了值。对于这个例子,我们可以说它只有两个元素(firstName和lastName)。我需要从myArrayList获取值并将它们与String进行比较,如果匹配则从bean获取值并将其放入map:

        Map<String,String> myMap;
        for(String element: myArrayList){
               if(element.equalsIgnoreCase("firstName")){
                   myMap.put("firstName", bean.getFirstName());
               }else if(element.equalsIgnoreCase("lastName")){
                   myMap.put("lastName", bean.getLastName());
               }
        }

问题是当你在myArrayList中有三十四个元素时,你会遇到性能问题(我假设),而且感觉不对。

我试过了:

        String name = null;
        String value = null;
        for(int i = 0; i < myArrayList.size(); i++){
            name = myArrayList.get(i);
            value = bean.get(name);
            myMap.put(name, value);
        }

但是行“value = bean.get(name);”在bean类中,方法get(String)是未定义的,实际上我们在bean类中没有这样的方法,它只有标准的getter和setter方法:

public class Bean implements Serializable {
    private String firstName;
    private String lastName;

    public String getFirstName(){
        return firstName;
    }

    public void setFirstName(String firstName){
        this.firstName = firstName;
    }

    public String getLastName(){
        return lastName;
    }

    public void setLastName(String lastName){
        this.lastName = lastName;
    }

}

现在我在思考如何能够提出一些优化逻辑的设计模式,而不会影响代码的性能。请随时提出问题,如果您需要更多信息,我会编辑。任何帮助是极大的赞赏。感谢。

编辑:shmosel的答案对我来说非常好,谢谢大家的帮助!干杯!

4 个答案:

答案 0 :(得分:1)

您可以尝试使用反射see javaDoc

但是,在真正需要之前,我不会建议使用它。可能,您应该重构代码以避免使用字段列表,您需要获取。

如果您决定使用反射,那么springframework中有ReflectionUtils

答案 1 :(得分:1)

@HankD和@Natalia提供了一些有效的解决方案,但我没有看到的另一个选项是重构Bean以支持get(String)方法:

public class Bean implements Serializable {
    private Map<String, String> properties = new HashMap<>();

    public String get(String property) {
        return properties.get(property);
    }

    public void set(String property, String value) {
        properties.put(property, value);
    }

    public String getFirstName(){
        return get("firstName");
    }

    public void setFirstName(String firstName){
        set("firstName", firstName);
    }

    public String getLastName(){
        return get("lastName");
    }

    public void setLastName(String lastName){
        set("lastName", lastName);
    }

}

答案 2 :(得分:1)

您的get(String)方法是一个非常好的主意,它只需要正确完成。这是我将如何做到的,它与你在Bean之外所做的非常相似,但它允许分离关注点,这是一件好事。

public String get(String field) {
    switch(field.toLowerCase()) {
        case "firstname":
            return firstName;
        case "lastname":
            return lastName;
        default:
            throw new IllegalArgumentException(field + " is an invalid field name.");
    }
}

我在这里使用了switch声明,因为Java Docs注意到:

  

Java编译器通常使用String对象生成比使用链接if-then-else语句的switch语句更高效的字节码。

如果你不能改变你的Bean类,那么你至少应该在你的循环中使用这个逻辑而不是你当前的逻辑,只是为了更快地switch语句并调用{{1一次而不是多次使用toLowerCase()

答案 3 :(得分:0)

这似乎是一种奇怪的做事方式。正如4castle所指出的,一些元素本身不太可能导致性能问题。您是否遇到性能问题?

如果是我,我会做这样的事情:

public static final String lastNameValue = "lastname";

for(String element: myArrayList){
    if(element != null) element = element.toLowerCase();

    if(lastNameValue.equals(element){
        myMap.put("lastName", bean.getLastName());
    } ....
}

每次调用此方法时,常量都会阻止构造新的String。您没有检查null元素。执行toLowerCase()一次比执行多次更有效。