GWT序列化TreeMap的排序/比较器

Mar*_*hke 4 java gwt serialization treemap guava

我有一个带有TreeMap的可序列化对象.

Map<String, Dogs> dogsByNames = Maps.newTreeMap(); // guava style
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好.现在忽略键的情况是必要的:

Map<String, Dogs> dogsByNames = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为String.CASE_INSENSITIVE_ORDER不是serialzable:

com.google.gwt.user.client.rpc.SerializationException:类型'java.lang.String $ CaseInsensitiveComparator'未包含在可由此SerializationPolicy序列化的类型集中,或者无法加载其Class对象.出于安全考虑,此类型不会被序列化:instance = java.lang.String$CaseInsensitiveComparator@f26f68

所以我创建了自己的一个:

private static abstract class MyComparator<T>
    implements
        Comparator<T>, // extends Ordering<T> do not work
        IsSerializable { // Serializable do not work
}

public static final MyComparator<String> CASE_INSENSITIVE_ORDER = new MyComparator<String>() {
    @Override
    public int compare(final String left, final String right) {
        if (null == left) {
            return (null == right) ? 0 : -1;
        } else if (null == right) {
            return 1;
        }
        return left.compareToIgnoreCase(right);
    }
};
Run Code Online (Sandbox Code Playgroud)

但这仍然行不通.

怎么了?

解:

protected static class MyOrdering // no-private!!!
    extends
        Ordering<String>
    implements
        IsSerializable {
    @Override
    public int compare(final String left, final String right) {
        if (null == left) {
            return (null == right) ? 0 : -1;
        } else if (null == right) {
            return 1;
        }
        return left.compareToIgnoreCase(right);
    }
}

public static final Ordering<String> CASE_INSENSITIVE_ORDER = new MyOrdering();
Run Code Online (Sandbox Code Playgroud)

小智 5

您创建的CASE_INSENSITIVE_ORDER是一个匿名类,无法在GWT中序列化.要使GWT可序列化,您需要

  1. 创建一个自定义顶级类(如

    CaseInsensitiveOrder implements Comparator<..>, Serializable {
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. CASE_INSENSITIVE_ORDER像你一样创建一个常量.

  3. 为该类(CaseInsensitiveOrder_CustomFieldSerializer)创建一个自定义字段序列化程序,它返回CASE_INSENSITIVE_ORDER实例deserialize().