我们有一些代码,它们根据坐标之间的距离对地址列表进行排序.这是通过collections.sort与自定义比较器完成的.
但是,有时会在列表中出现没有坐标的地址,从而导致出现NullPointerException.我最初的想法是让比较器返回0作为地址的距离,其中至少有一个坐标为空.我担心这可能会导致列表中"有效"元素的订单损坏.
所以在比较器ok中返回空数据的'0'值,或者有更清晰的方法来解决这个问题.
Sjo*_*erd 77
处理它就像null无限远的手段.从而:
comp(1234, null) == -1comp(null, null) == 0comp(null, 1234) == 1通过这种方式,您可以获得一致的订购.
Cow*_*wan 24
为了扩展WilliSchönborn的答案,我来到这里说google-collections正是你在这里所追求的.
在一般情况下,您可以编写自己的方法Comparator来忽略空值(假设非null,因此它可以专注于重要的逻辑),然后使用Ordering来处理空值:
Collections.sort(addresses, Ordering.from(new AddressComparator()).nullsLast());
但是,在您的情况下,它是用于排序的地址(坐标)中的数据,对吧?在这种情况下,google-collections 更有用.所以你可能会有类似的东西:
// Seems verbose at first glance, but you'll probably find yourself reusing 
// this a lot and it will pay off quickly.
private static final Function<Address, Coordinates> ADDRESS_TO_COORDINATES = 
  new Function<Address, Coordinates>() {
      public Coordinates apply(Address in) {
          return in.getCoordinates();
      }
  };
private static final Comparator<Coordinates> COORDINATE_SORTER = .... // existing
然后当你想要排序:
Collections.sort(addresses,
    Ordering.from(COORDINATE_SORTER)
            .nullsLast()
            .onResultOf(ADDRESS_TO_COORDINATES));
这就是谷歌收藏的力量真正开始得到回报的地方.
我对此的看法是,你试图做的任何事情都是为了"改善" null坐标,只是在克服裂缝.你真正需要做的是找到并修复注入虚假null坐标的错误.
根据我的经验,NPE错误的侵扰通常是由以下不良编码习惯引起的:
null,以避免产生空阵列或集合,null在应该抛出异常时返回,或者null时,有一个更好的解决方案来表示"没有价值".(对"无价值"问题的更好解决方案通常涉及重写代码,以便您不需要代表此代码和/或使用非空值;例如,空字符串,特殊实例,保留值.您可以总能找到更好的解决方案,但你经常可以.)
如果这描述了您的应用程序,您应该花时间根除代码问题,而不是考虑隐藏NPE的方法.
我的解决方案(对于看这里的人可能有用)是做比较法线,空值不是由0替换,而是可能的最大值(例如Integer.MAX_VALUE).如果您的值本身为0,则返回0不一致.这是一个正确的示例:
        public int compare(YourObject lhs, YourObject rhs) {
            Integer l = Integer.MAX_VALUE;
            Integer r = Integer.MAX_VALUE;
            if (lhs != null) {
                l = lhs.giveMeSomeMeasure();
            }
            if (rhs != null) {
                r = rhs.giveMeSomeMeasure();
            }
            return l.compareTo(r);
        }
我只是想补充一点,你不需要整数的最大值.这取决于你的giveMeSomeMeasure()方法可以返回什么.例如,如果您比较天气的摄氏度,则可以将l和r设置为-300或+300,具体取决于您要设置空对象的位置 - 指向列表的头部或尾部.
如果您使用的是Java 8,则Comparator类中有2个新的静态方法,它们很方便:
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator)
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator)
比较将是null安全的,您可以选择将null值放置在排序序列中的位置。
下面的例子:
List<String> monkeyBusiness = Arrays.asList("Chimp", "eat", "sleep", "", null, "banana",
            "throw banana peel", null, "smile", "run");
Comparator<? super String> comparator = (a, b) -> a.compareTo(b);
monkeyBusiness.stream().sorted(Comparator.nullsFirst(comparator))
            .forEach(x -> System.out.print("[" + x + "] "));
会打印:[null] [null] [] [Chimp] [banana] [eat] [run] [sleep] [smile] [throw banana skin]
| 归档时间: | 
 | 
| 查看次数: | 48625 次 | 
| 最近记录: |