繁体   English   中英

内联对象比较Java

[英]Inline Object Comparison Java

我正在尝试使用以下方法对arraylist进行排序。 我希望美国先行,其次是英国,等等。但是,这似乎没有做任何事情。 我究竟做错了什么?

    orderedTerritories.sort((o1, o2) -> {
        if (o1.getCode().equals("US*"))
            return 1;
        else if (o2.getCode().equals("US*"))
            return 0;
        else if (o1.getCode().contains("UK") && o1.getContains() != null)
            return 1;
        else if (o2.getCode().contains("UK") && o2.getContains() != null)
            return 0;
        else if (o1.getCode().equals("DE*"))
            return 1;
        else if (o2.getCode().equals("DE*"))
            return 0;
        else if (o1.getCode().equals("JP"))
            return 1;
        else if (o2.getCode().equals("JP"))
            return 0;
        else if (o1.getCode().equals("IN"))
            return 1;
        else if (o2.getCode().equals("IN"))
            return 0;
        else return 1;
    });

您的排序逻辑不会检查两个代码是否相同,并且在o1.getCode()小于o2.getCode()时也返回0而不是负值。 不这样做就违反了比较器合同。

根据您的排序逻辑,您不能简单地依靠国家/地区代码的字符串表示形式进行排序。 为了缓解这种情况,您需要为每个国家/地区定义自定义订购值。 我假设您无法修改get code方法以返回Enum或某些自定义对象。 在这种情况下,您可以定义国家代码和订单之间的映射,并使用该订单值进行排序。 这是一个例子:

评论之一已经在建议类似的方法。

     private static Map<String, Interger> codeToOrderMap = new HashMap<>();

    static{
     codeToOrderMap.put("US*", 0);
     codeToOrderMap.put("UK", 1);
     codeToOrderMap.put("DE*", 2);
     codeToOrderMap.put("JP", 3);
     codeToOrderMap.put("IN", 4);
    }

    orderedTerritories.sort((o1, o2) ->
codeToOrderMap.get( o1.getCode() ).compareTo( codeToOrderMap.get( o2.getCode() );

如果不使用上述方法或自定义代码,则必须编写一个很长的凌乱比较器。

我倾向于同意Lew Bloch的观点,即您应该通过使用枚举来使用面向对象的方法。

我不明白您对Lew Bloch发表的评论的回应。 您说:“因为我不能对其进行硬编码,所以不能。有没有办法在Java中进行简单排序?” 但是您已经在对当前代码中的值进行硬编码。 例如,您的代码中包含以下内容:

o1.getCode().equals("US*")在此语句中,“ US *”是硬编码的。

这是仅使用美国和英国代码的枚举方法的示例:

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class Example implements Comparable<Example>
{
  public enum CountryCode{
    US,UK
  }

  public static void main(String[] args)
  {
    List<Example> codeList = new ArrayList<>();
    codeList.add(new Example(CountryCode.UK));
    codeList.add(new Example(CountryCode.US));

    System.out.println("Before sort: "+codeList);
    Collections.sort(codeList);
    System.out.println("After sort: "+codeList);

  }

  private CountryCode countryCode;

  public Example(CountryCode code){
    this.countryCode = code;
  }

  public CountryCode getCountryCode(){
    return countryCode;
  }

  public int compareTo(Example other){
    return this.countryCode.compareTo(other.getCountryCode());
  }

  public String toString(){
    return "Example: "+countryCode.toString();
  }
}

由于枚举按此顺序包含美国和英国,并且Example类针对其执行compareTo而遵循该枚举,因此对Example List进行了排序,以使国家代码为US的Example对象排在具有英国国家代码的Example对象之前。

输出

Before sort: [Example: UK, Example: US]
After sort: [Example: US, Example: UK]

最后一项 :我不清楚您的代码值中“ *”的含义。 如果存在您未指定的要求,则此方法可能无法按预期工作。

谢谢,我考虑了你们对以下有效解决方案的看法:

       List<Territory> orderedTerritories = new LinkedList<>();
       List<Integer> integerValues = new ArrayList<>();
       Map<Integer, Territory> intToTerritoryMap = new HashMap<>();
       int i = 5;
       for (Territory territory : finalSet) {
            int index = 5;
            if (territory.getCode().equals("US*"))
                index = 0;
            else if (territory.getCode().contains("UK") && territory.getContains() != null)
                index = 1;
            else if (territory.getCode().equals("DE*"))
                index = 2;
            else if (territory.getCode().equals("JP"))
                index = 3;
            else if (territory.getCode().equals("IN"))
                index = 4;
            if (index < 5) {
                intToTerritoryMap.put(index, territory);
                integerValues.add(index);
            } else {
                intToTerritoryMap.put(i, territory);
                integerValues.add(i++);
            }
        }
        Collections.sort(integerValues);

        integerValues.forEach(j -> {
            orderedTerritories.add(intToTerritoryMap.get(j));
        });

        return orderedTerritories;

这是冗长而繁琐的数字编码。 我希望有一个更简单的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM