【问题标题】:Custom Comparator to sort list of states, counties and zip codes自定义比较器对州、县和邮政编码列表进行排序
【发布时间】:2014-03-28 23:23:06
【问题描述】:

我很难编写比较器来使用以下字符串字段对自定义对象列表进行排序: 1. Branch Class --> 可以是州、县或邮政编码,用于识别是哪个数据字段;不能为空 2. State --> State Name,不能为空 3. Geography --> if branch class.equals'county',就是县名,可以为空 4. 邮编 --> 邮政编码。州和县可以为空 5. ParentNodeId --> 应该适用于这棵树的父节点的名称。例如,一个州没有父节点(空字符串),而县的 parentNodeId 是该州,而邮政编码的 parentNodeId 是县。因此,对于分支 = "state"、邮政编码 "36003" 的地理对象,parentNodeId 应该是 Autauga 并且 state 是 "AL"。对于分支 =“county”且 geography =“Autauga”的地理对象,则 parentNodeId 为“AL”。

当前对象列表的形式为:州-州-州-县-县-邮政编码-邮政编码

虽然我正在寻找一份清单

-状态

-- 县

-- 邮政编码

-- 邮政编码

-- 县

-- 邮政编码

-状态

-- 县

等等。

我的审判仍然缺少我不知道的案件。这是我的代码

public static final Comparator<Geography> BY_STATE_COUNTY_ZIP_COMPARATOR = new Comparator<Geography>() {

public int compare(final Geography obj1, final Geography obj2) {

    if (obj1.getZip().equals("89420") || obj2.getZip().equals("89420") || obj1.getGeography().equals("Mono")
            || obj2.getGeography().equals("Mono")) {
        System.out.println("hdfhd");
    }

    if (obj1.getBranchClass().equalsIgnoreCase(obj2.getBranchClass())) {
        return this.similarBranchComparison(obj1, obj2);
    }
    else {
        // Different branches
        final int x = this.differentBranchesComparison(obj1, obj2);
        return x;
    }

}

private int differentBranchesComparison(final Geography obj1,
        final Geography obj2) {

    if ((obj1.getZip().equals("89420") && obj1.getParentNodeId().equals("Mono"))
            || ((obj2.getZip().equals("89420") && obj2.getParentNodeId().equals("Mono")))) {
        System.out.println("hdfhd");
    }

    // Same states - Obj1 is state
    if (obj1.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.STATE_LEVEL)
            && obj1.getState().equalsIgnoreCase(obj2.getState())) {
        // obj2 should be greater
        return -1;
    }
    // Same states - Obj2 is state
    else if (obj2.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.STATE_LEVEL)
            && obj1.getState().equalsIgnoreCase(obj2.getState())) {
        // obj1 should be greater
        return 1;
    }
    // Different states - obj1 OR Obj2 is state
    else if (((obj1.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.STATE_LEVEL)) || (obj2
            .getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.STATE_LEVEL)))
            && !(obj1.getState().equalsIgnoreCase(obj2.getState()))) {
        // Delegate to state comparison
        return new CompareToBuilder().append(obj1.getState(), obj2.getState()).toComparison();
    }
    // Same states - Same counties (County - Zip)
    else if (obj1.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.COUNTY_LEVEL)
            && ((obj1.getState().equalsIgnoreCase(obj2.getState())) && (obj1.getGeography()
                    .equalsIgnoreCase(obj2.getParentNodeId())))) {
        // obj2 (zip) should be greater
        return -1;
    }
    // Same states - Same counties (Zip - County)
    else if (obj2.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.COUNTY_LEVEL)
            && ((obj1.getState().equalsIgnoreCase(obj2.getState())) && (obj1.getParentNodeId()
                    .equalsIgnoreCase(obj2.getGeography())))) {
        // obj1 should be greater
        return 1;
    }
    // Same states different counties (County - zip)
    else if ((obj1.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.COUNTY_LEVEL))
            && (obj1.getState().equalsIgnoreCase(obj2.getState()) && !(obj1.getGeography()
                    .equalsIgnoreCase(obj2.getParentNodeId())))) {
        return new CompareToBuilder().append(obj1.getGeography(), obj2.getParentNodeId()).toComparison();
    }

    // Same states different counties (Zip - County)
    else if ((obj2.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.COUNTY_LEVEL))
            && (obj1.getState().equalsIgnoreCase(obj2.getState()) && !(obj1.getParentNodeId()
                    .equalsIgnoreCase(obj2.getGeography())))) {
        return new CompareToBuilder().append(obj1.getParentNodeId(), obj2.getGeography()).toComparison();
    }

    // Different States
    else if (((obj1.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.COUNTY_LEVEL)) || (obj2
            .getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.COUNTY_LEVEL)))
            && !(obj1.getState().equalsIgnoreCase(obj2.getState()))) {
        return new CompareToBuilder().append(obj1.getState(), obj2.getState()).toComparison();
    }
    return 0;

}

private int similarBranchComparison(final Geography obj1,
        final Geography obj2) {
    // State-State, County - County, Zip-Zip
    // State-State
    if (obj1.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.STATE_LEVEL)) {
        return new CompareToBuilder().append(obj1.getState(), obj2.getState()).toComparison();
    }
    // County - County
    else if (obj1.getBranchClass().equalsIgnoreCase(ASDGeographyBasedDashboardVO.COUNTY_LEVEL)) {
        if (obj1.getState().equalsIgnoreCase(obj2.getState())) {
            // Compare Counties within the same state
            return new CompareToBuilder().append(obj1.getGeography(), obj2.getGeography()).toComparison();
        }
        else {
            // Compare Counties within different states
            return new CompareToBuilder().append(obj1.getState(), obj2.getState()).toComparison();
        }
    }
    else {
        // Zip - Zip
        if (obj1.getState().equalsIgnoreCase(obj2.getState())) {
            if (obj1.getParentNodeId().equalsIgnoreCase(obj2.getParentNodeId())) {
                return new CompareToBuilder().append(obj1.getZip(), obj2.getZip()).toComparison();
            }
            else {
                return new CompareToBuilder().append(obj1.getParentNodeId(), obj2.getParentNodeId())
                        .toComparison();
            }
        }
        else {
            // Compare Zip codes within different states
            return new CompareToBuilder().append(obj1.getState(), obj2.getState()).toComparison();
        }

    }
}
};

【问题讨论】:

  • 检查新的 Java8 特性 Streams 和过滤、减少等的酷方法。我可以检查你的需求并在明天编写一些东西,但今晚不行 :-(
  • 不幸的是,我仅限于 java 1.6
  • 然后从 Google 签出 Guava 库。这些功能已经很少了。 FluentIterable、Optional 等等。
  • 不幸的是,我无法将任何库添加到代码库中。完成这件作品有一些限制,这让我很难。 treeMap/treeSet 会为此工作吗?

标签: java algorithm sorting comparator icomparable


【解决方案1】:

这应该是一个简单的比较器,您首先比较州,然后是县,然后是 zip。所以这假设您可以编写 getState()、getCounty() 和 getZip() 方法,并且可以编写州、县和 zip 的比较。如果您无法从所有不同类型中获取状态,那么您就无法比较它们。

这是一些伪代码。

Comparator<Geography> comparator = new Comparator<>() {
    public int compare(final Geography obj1, final Geography obj2) {
        state1 = getState(obj1);
        state2 = getState(obj2);

        int retCode = state1.compare(state2);
        if (retCode != 0)
            return retCode;

        county1 = getCounty(obj1);
        county2 = getCounty(obj2);

        retCode = county1.compare(county2);
        if(retCode != 0)
           return retCode;

        zip1 = getZip(obj1);
        zip2 = getZip(obj2);

        retCode = zip1.compare(zip2);
        return retCode;
   }
}

【讨论】:

  • 您是否认为它涵盖了比较邮政编码和县的情况......或者您比较不同州的两个县,或者当您比较两个相似的邮政编码但在一个州的不同县时更糟?我遇到的一个问题是,如果地理对象表示邮政编码,则县不可用
  • 好的,所以如果没有县,则无法比较县。因此,除非您可以将 zip 映射到某个县,否则您要求的这种排序是不可能的。您也许可以使用 zipwise.com/webservices 之类的东西来帮助解决这个问题。
猜你喜欢
  • 2020-07-11
  • 1970-01-01
  • 2020-07-09
  • 2019-05-06
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多