java比较多个值并找到最佳匹配

时间:2017-07-07 10:38:16

标签: java oracle

我需要在数据库记录中找到最匹配的员工薪水:

Name:   City:     State:

A       (null)    (null)

A       (null)    DEL

(null)  (null)    (null)

A        SAKET    DEL

匹配顺序应为:

1。 NAME = name,STATE = state,CITY = city

2。 NAME = name,STATE = state,CITY = NULL

3. NAME = name,STATE = NULL,CITY = NULL

4. NAME = NULL,STATE = NULL,CITY = NULL

表示在所有属性匹配的行中 - 应该选择它,如果我们没有这种数据,我们应该选择下一个最佳选项,如选择州和城市为NULL等。

我的代码如下,给我正确的结果,但我需要一种更有效的方法。

    private static BigDecimal getsalaryForBestMatch(ResultSet results, EmployeeRq request) throws Exception{
    BigDecimal salary = null;
    BigDecimal salaryWithState = null;
    BigDecimal salaryWithName = null;
    BigDecimal salaryWithNoMatch = null;
     while (results.next()) {

        String billerName = results.getString("EMP_NAME") != null ? results.getString("EMP_NAME").trim() : null;
        String city = results.getString("CITY") != null ? results.getString("CITY").trim() : null;
        String state = results.getString("STATE") != null ? results.getString("STATE").trim() : null;

        BigDecimal salaryRslt = null;

        if(results.getString("SALARY") != null){
            salaryRslt = BigDecimal.valueOf(results.getDouble("SALARY"));               
        }  
        if(billerName != null && !billerName.equals("") && billerName.equals(request.getBillPaymentsalaryCalculateInfo().getBillerName())){
            if(city != null && !city.equals("") && city.equals(request.getMsgRqHdr().getCity()) &&
                    state != null && !state.equals("") && state.equalsIgnoreCase(request.getMsgRqHdr().getstate())){
                salary = salaryRslt;
                break;
            } else if((city == null || city.equals("")) && state != null && !state.equals("") &&
                    state.equalsIgnoreCase(request.getMsgRqHdr().getState())){
                salaryWithState = salaryRslt;                   
            } else if((city == null || city.equals("")) && (state == null || state.equals(""))){
                salaryWithName = salaryRslt;                    
            }
        } else if((billerName == null || billerName.equals("")) && (city == null || city.equals("")) && 
                (state == null || state.equals(""))){
            salaryWithNoMatch = salaryRslt;             
        }
     }

     if(salary != null){
         return salary;
     } else if(salaryWithState != null){
         salary = salaryWithState;
     } else if(salaryWithName != null){
         salary = salaryWithName;
     } else if(salaryWithNoMatch != null){
         salary = salaryWithNoMatch;
     } 

     return salary;

}

编辑:我不想使用3个额外变量:salaryWithState,salaryWithName,salaryWithNoMatch。

2 个答案:

答案 0 :(得分:0)

我想简单地说明如何实现这一点,所以我实际上没有测试并检查它是否会给你合适的工资。

public BigDecimal getSalaryForBestMatch(ResultSet resultSet, PaymentSalaryInfo paymentSalaryInfo) {
    Map<String, Supplier<String>> m1 = new HashMap<>();
    m1.put("EMP_NAME", paymentSalaryInfo::getBillerName);
    m1.put("STATE", paymentSalaryInfo::getState);
    m1.put("CITY", paymentSalaryInfo::getCity);

    Map<String, Supplier<String>> m2 = new HashMap<>();
    m2.put("STATE", paymentSalaryInfo::getState);
    m2.put("CITY", paymentSalaryInfo::getCity);

    Map<String, Supplier<String>> m3 = new HashMap<>();
    m3.put("CITY", paymentSalaryInfo::getCity);


    Optional<String> salary = Optional.empty();

    while(resultSet.next() && !salary.isPresent()) {
        salary = apply(m1, resultSet);
        //check salary and then apply(m2, resultSet) ....
    }

    return salary.isPresent() ? new BigDecimal(salary.get()) : null;
}


public Optional<String> apply(Map<String, Supplier<String>> filter, ResultSet resultSet) {
    boolean allMatch = filter.entrySet().stream().allMatch(entry -> {
        String value = resultSet.getString(entry.getKey());

        return value != null && value.equals(entry.getValue().get());
    });

    return allMatch ? Optional.of(resultSet.getString("salary")) : Optional.empty();
}

答案 1 :(得分:0)

我使用数组以不同的方式编写了相同的逻辑。如果您的环境可以负担使用数组,则可以使用此代码。但我还没有测试过代码。

 private static BigDecimal getsalaryForBestMatch(ResultSet results, EmployeeRq request) throws Exception{
    BigDecimal salary = null;
    int matchCount = 0;
    String rBillerName = request.getBillPaymentsalaryCalculateInfo().getBillerName();
    String rCity = request.getMsgRqHdr().getCity();
    String rState = request.getMsgRqHdr().getstate();

    String [] truthArray = new String[] {rBillerName, rCity, rState};

    while (results.next()) {
        String billerName = results.getString("EMP_NAME") != null ? results.getString("EMP_NAME").trim() : null;
        String city = results.getString("CITY") != null ? results.getString("CITY").trim() : null;
        String state = results.getString("STATE") != null ? results.getString("STATE").trim() : null;
        BigDecimal salaryRslt = results.getString("SALARY") != null ? BigDecimal.valueOf(results.getDouble("SALARY")): null;

        String [] testArray = new String[] {billerName, city, state};

        int localMatchCount = 0;
        for(int i = 0; i < testArray.length; i++) {
            if(testArray[i] != null && testArray[i].equals(truthArray[i]))
                localMatchCount++;
            else {
                break;
            }
        }

        if(localMatchCount >= matchCount){
            matchCount = localMatchCount;
            salary = salaryRslt;
        }
    }
    return salary;
}