重构java代码 - arraylist包含if / else

时间:2017-08-02 19:41:58

标签: java java-8

是否有可能以优雅的方式重构以下if / else部分?请分享您的专业知识和反馈。

if(onlineAreaPrioList.contains("ladies")){
            dominantOnlineArea = "ladies";
        }else if(onlineAreaPrioList.contains("kids")){
            dominantOnlineArea = "kids";
        }else if(onlineAreaPrioList.contains("men")){
            dominantOnlineArea = "men";
        }else if(onlineAreaPrioList.contains("home")){
            dominantOnlineArea = "home";
        }

注意:优先顺序=女士>孩子>男士>家

输出: hashmap中的值:{men = 2,ladies = 2,home = 2,kids = 1}

onlineAreaPrioList中的值:[男士,女士,家]

ComputedOnlineArea:ladies

以下是整个代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import dto.ProductDTO;


public class Test {

    static Map<String, Integer> freq = new HashMap<String, Integer>();

    public static void main(String[] args) {
        List<ProductDTO> recentlyBoughtList = recentlyBought();
        List<ProductDTO> recentlyViewedList = recentlyViewed();

        String finalOnlineArea = getDominantOnlineArea(recentlyViewedList,recentlyBoughtList);
        System.out.println("ComputedOnlineArea: "+finalOnlineArea);
    }

    private static String getDominantOnlineArea(List<ProductDTO> recentlyViewedList,List<ProductDTO> recentlyBoughtList) {

        for (ProductDTO productDTO:  recentlyViewedList) {
            countPrimaryOnlineArea(productDTO);
            addSecondaryOnlineAreaWithPrimary(productDTO);
        }

        for (ProductDTO productDTO:  recentlyBoughtList) {
            countPrimaryOnlineArea(productDTO);
            addSecondaryOnlineAreaWithPrimary(productDTO);
        }

        System.out.println("values in hashmap :"+freq);

        return getOnlineAreaBasedOnDefaultPriorityOrder();

    }

    private static String getOnlineAreaBasedOnDefaultPriorityOrder() {

        String dominantOnlineArea = null;
        Set<String> onlineAreaPrioList = new HashSet<String>();

        int maxValueInMap=(Collections.max(freq.values()));  
        for (Entry<String, Integer> entry : freq.entrySet()) {  
            if (entry.getValue()==maxValueInMap) {
                //System.out.println(entry.getKey());  
                onlineAreaPrioList.add(entry.getKey());
            }
        }

        System.out.println("values in onlineAreaPrioList :"+onlineAreaPrioList);

        if(onlineAreaPrioList.contains("ladies")){
            dominantOnlineArea = "ladies";
        }else if(onlineAreaPrioList.contains("kids")){
            dominantOnlineArea = "kids";
        }else if(onlineAreaPrioList.contains("men")){
            dominantOnlineArea = "men";
        }else if(onlineAreaPrioList.contains("home")){
            dominantOnlineArea = "home";
        }
        return dominantOnlineArea;
    }

    private static void countPrimaryOnlineArea(ProductDTO productDTO) {
        String pOnlineArea = productDTO.getPrimaryOnlineAreaId();
        if(OnlineAreaNotEmptyAndNotNull(pOnlineArea))
            checkAndIncreaseOnlineAreaCount(pOnlineArea);
    }

    private static boolean OnlineAreaNotEmptyAndNotNull(String onLineArea) {
        boolean onlineAreaFlag = false;
        if(null!=onLineArea)
            onlineAreaFlag = true;
        return onlineAreaFlag;
    }

    private static void addSecondaryOnlineAreaWithPrimary(ProductDTO productDTO) {
        String onlineArea = productDTO.getOnlineAreaIds();
        if(OnlineAreaNotEmptyAndNotNull(onlineArea)) {
        if(onlineArea.contains("|")) {
            String[] onlineAreaSplit = onlineArea.split("\\|");
            for(String online : onlineAreaSplit) {
                checkAndIncreaseOnlineAreaCount(online);
            }

        }else {
            checkAndIncreaseOnlineAreaCount(onlineArea);
        }
        }

    }

    private static void checkAndIncreaseOnlineAreaCount(String onlineArea) {
        int count = freq.containsKey(onlineArea) ? freq.get(onlineArea) : 0;
        freq.put(onlineArea, count + 1);
    }


    private static List<ProductDTO> recentlyBought() {
        List<ProductDTO> recentlyBoughtList= new ArrayList<ProductDTO>();

        ProductDTO productDTO1 = new ProductDTO();
        productDTO1.setPrimaryOnlineAreaId("ladies");
        productDTO1.setOnlineAreaIds("ladies");

        ProductDTO productDTO2 = new ProductDTO();
        productDTO2.setPrimaryOnlineAreaId("men");
        //productDTO2.setOnlineAreaIds("men"); //comment

        recentlyBoughtList.add(productDTO1);
        recentlyBoughtList.add(productDTO2);
        return recentlyBoughtList;
    }

    private static List<ProductDTO> recentlyViewed() {
        List<ProductDTO> recentlyViewedList= new ArrayList<ProductDTO>();

        ProductDTO productDTO1 = new ProductDTO();
        productDTO1.setPrimaryOnlineAreaId("home");
        productDTO1.setOnlineAreaIds("home");

        ProductDTO productDTO2 = new ProductDTO();
        //productDTO2.setPrimaryOnlineAreaId("men"); //comment
        productDTO2.setOnlineAreaIds("men|kids");

        recentlyViewedList.add(productDTO1);
        recentlyViewedList.add(productDTO2);
        return recentlyViewedList;
    }



}

package dto;

public class ProductDTO {
    private String primaryOnlineAreaId;
    private String onlineAreaIds;
    private String ageId;

    public String getPrimaryOnlineAreaId() {
        return primaryOnlineAreaId;
    }
    public void setPrimaryOnlineAreaId(String primaryOnlineAreaId) {
        this.primaryOnlineAreaId = primaryOnlineAreaId;
    }
    public String getOnlineAreaIds() {
        return onlineAreaIds;
    }
    public void setOnlineAreaIds(String onlineAreaIds) {
        this.onlineAreaIds = onlineAreaIds;
    }
    public String getAgeId() {
        return ageId;
    }
    public void setAgeId(String ageId) {
        this.ageId = ageId;
    }


}

3 个答案:

答案 0 :(得分:8)

一种方法是将if s链转换为增强型for循环:

for (String kind : new String[] {"ladies", "kids", "men", "home"}) {
    if (onlineAreaPrioList.contains(kind)) {
        dominantOnlineArea = kind;
        break;
    }
}

考虑将“魔术字符串”(即"ladies""kids""men""home")替换为在适当级别定义的字符串常量。

另一种方法是将“魔术字符串”替换为enum s,这样您就可以将onlineAreaPrioList的类型切换为EnumSet

public enum PriorityKind {
    LADIES, KIDS, MEN, HOME 
}
...
EnumSet<PriorityKind> onlineAreaPrioList = new EnumSet<>();

答案 1 :(得分:5)

实际上将它们保留为String可能不是一个好主意,因为您需要明确优先级。因此,定义Enum可能会更好:

enum Priority {

    LADIES(1),
    KIDS(2),
    MEN(3),
    HOME(4);

    private final int weight;

    Priority(int weight) {
        this.weight = weight;
    }

    public int getWeight() {
        return weight;
    }
}

然后用法是:

Stream.of(Priority.KIDS, Priority.MEN)
            .max(Comparator.comparing(Priority::getWeight))
            .orElse(null);

答案 2 :(得分:3)

另一种选择是使用Stream API,它可以产生更优雅的解决方案:

dominantOnlineArea = Stream.of("ladies", "kids", "men", "home")
  .filter(onlineAreaPrioList::contains)
  .findFirst()
  .orElse(null); // handle the empty case as you wish