- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有 Multiset<String>
对象,我将其序列化为 Json。我正在使用 Gson 执行此操作,如下所示:
Multiset<String> mset = ... ;
Gson gson = new Gson();
Files.write(Gson.toJson(mset), new File(abosulte_path_string), Charset.defaultCharset());
当我尝试反序列化它时,我会执行以下操作:
String json_string = ... // read from file
Type type = new TypeToken<Multiset<String>>(){}.getType();
Multiset<String> treated = gson.fromJson(json_string, type);
我收到这个错误:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.google.common.collect.Multiset
当我打开 json 文件时,我看到 Multiset<String>
object 确实表示为 ArrayList([string1,string2,...]),重复具有 count > 1
的字符串在多重集中。
当然,我可以将其转换为 ArrayList,然后使用 create(Iterable<>)
构造函数来获取我的多重集,但这似乎是一种迂回的方式。是否有更直接的方法反序列化 json 对象以检索我的多重集?
最佳答案
编辑:在这种情况下,似乎有一种更简单的方法可以解决这个问题,即注册一个 instance creator。对于多重集:
private static class MultisetInstanceCreator implements InstanceCreator<Multiset<?>> {
@Override
public Multiset<?> createInstance(Type type) {
return HashMultiset.create();
}
}
Gson gson = new GsonBuilder()
.registerTypeAdapter(Multiset.class, new MultisetInstanceCreator())
.create();
实例创建者只是定义了应该如何创建 Multiset,因为 Guava 集合没有默认构造函数(无论如何 Multiset 是接口(interface))。
原始答案:我不确定这是否是实现您想要的效果的最佳或最简单方法,但这是我们最近解决类似问题的一种方法(在我们的案例中它正在反序列化为 ImmutableMap)。
基本思路是注册一个custom deserialiser它基本上完成了您已经发现的可能解决方案:反序列化为 ArrayList,然后将其转换为 Multiset。这里的优点是您只需注册一次自定义反序列化器,而不必到处都知道才能首先使用 ArrayList 类型。
这个自定义反序列化器看起来像这样:
private static class MultisetDeserializer implements JsonDeserializer<Multiset<?>> {
@Override
public Multiset<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
ParameterizedType listType = new ListParameterizedType(typeArguments);
List<?> list = context.deserialize(json, listType);
return HashMultiset.create(list);
}
}
简而言之,这会将要反序列化的预期类型(例如,在您的情况下为 new TypeToken<Multiset<String>>(){}.getType()
)转换为 ParameterizedType
获取类型参数(在您的示例中为 String)。然后它创建一个新的 ParameterizedType,它是具有相同类型参数的 ArrayList 的类型(如下所示)。使用上下文将 JSON 反序列化为这种新类型后,您所要做的就是调用 HashMultiset.create
.
ListParameterizedType
看起来像这样:
private static class ListParameterizedType implements ParameterizedType {
private final Type[] typeArguments;
private ListParameterizedType(Type[] typeArguments) {
this.typeArguments = typeArguments;
}
@Override
public Type[] getActualTypeArguments() {
return typeArguments;
}
@Override
public Type getRawType() {
return ArrayList.class;
}
@Override
public Type getOwnerType() {
return null;
}
}
请注意,您可以替换 ArrayList
这里几乎可以使用任何列表类,只要它具有一个类型参数和一个默认构造函数即可。
可能还有更简单的方法来实现同样的事情,例如,您可以通过检查 JsonElement
来手动进行一些解析。使用类似 isJsonArray()
的方法.这可以避免您创建一个 ArrayList,您随后会立即丢弃它。
关于java - Json Multiset 与 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21973141/
我想找出一个算法来验证一个multiset是否是另一个multiset的子集和的并集,但是我自己奋斗了几个小时失败了。 详情如下: Multiset A:一个正整数集 Multiset B:一个正整数
在我看来,它们是一样的。但在 Visual Studio 2015 中,它们肯定是不同的。 //Ok, work properly multiset > ms1; ms1.insert(10); ms
一 问题描述 并行处理中的编程规范之一是生产者/消费者范型,可以使用具有管理者进程和多个客户端进程的系统来实现。客户可以是生产者、消费者等。管理者跟踪客户进程。每个进程都有一个成本,允许具有相同成本的
如果能帮助调试多重集容器的一些奇怪行为,我将不胜感激。有时,容器似乎停止排序。这是一个不常见的错误,很长一段时间后才在一些模拟中出现,而且我缺乏想法。 (我是一个业余程序员--欢迎各种建议。) 我的容
我有一个带有自定义谓词函数的多重集,例如 multiset其中 MyCompFunc 查看 MyClass 对象的属性。在应用程序的运行过程中,对象可能会以某种方式发生变化,从而导致它们被重新排序。
我最近发现 multiset STL 中的实现实际上在树中保留相同重复元素的不同拷贝。我之前的期望是它在内部使用 map并只保留重复元素的计数。 与仅保持计数相比,这种实现在什么情况下可以带来好处?
假设你有一个如下表: CREATE TABLE EMPLOYEE_SALES ( EMPLOYEE_ID NUMBER, PRODUCT_ID NUMBER, SALE_AM
我正在使用指向对象的 std::multiset 指针来在我的游戏中实现 Z 排序,因此我不需要在每次插入时对结构进行排序。我使用比较器按对象的深度插入: struct rendererCompara
将长字符串转换为包含单词和计数的数据结构的最佳方法是什么。 我会做 .split("") 来分割空格并大概创建一个数组列表,然后可能会遍历数组列表并将每个项目添加到 HashMap 或多集?我不确定执
我在为以下用例决定更好的设计模式时遇到了麻烦。 我们的项目中有两个模块, 模块 1、模块 2 对于访问每个模块的用户,有两组四个权利:一组用于模块 1,另一组用于模块 2。 现在,根据用户角色的正确组
我的 MultiSet 类的一些方法存在一些问题。这是一个测试器,MultiSet 类应该得到输出:“成功!”如果它工作正常。这是测试仪: public class MultiSetTest {
多线程访问是否需要同步 pair equal_range (const value_type& val) const; 由于 equal_range 是读取操作,因此可能不需要。请给出意见。 最佳答案
我需要一个 Guava MultiSet.Entry 的比较器,用于首先按计数排序,然后按字符串排序。但是,我遇到了编译器问题,并且我认为我得到了一些泛型错误的信息。 编译: Comparator>
我正在寻找计算 std::multiset 中元素的不同出现次数的代码。我有以下代码 #include #include #include #include struct test {
我能否以某种方式重载任何 std::multiset 的运算符(就像您使用“()”来创建自定义 comapre 函数一样)以便当交换 multiset 中的 2 个元素时,来自另一个 vector 的
我需要找到树中的最佳路径,树是multiset 元素的所有可能组合。例如对于这个 multiset:A - B - C,树将由所有 6 种可能的组合组成:A - B - C |A - C - B |B
下午好,我有一个C++类Range它实现了一个 operator ranges_type 使用. 由于 multiset 构造函数没有指定自定义比较仿函数,它使用 std::less operato
我有 std::multiset 如果我从 std::multiset::begin() 迭代到 std::multiset::end( ) 我将得到排序的元素。除了从 std::multiset::
我想打印出多重集中的每个重复项,但不知何故迭代器对我来说表现得很奇怪。如何修复此代码?这段代码导致了一个永远的循环,这让我很惊讶。 #include #include #include stat
我有一个 std::multiset存储 class A 的元素.我提供了自己的 operator< 实现对于这个类。我的问题是,如果我在这个多重集中插入两个等效对象,它们的顺序是否得到保证?例如
我是一名优秀的程序员,十分优秀!