Skip to content

Commit e0cace3

Browse files
committed
support Set
1 parent adf4faa commit e0cace3

File tree

2 files changed

+84
-13
lines changed

2 files changed

+84
-13
lines changed

src/main/java/com/github/jsoniter/Codegen.java

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class Codegen {
2828
put(Long.class.getName(), "Long.valueOf(iter.readLong())");
2929
put(String.class.getName(), "iter.readString()");
3030
}};
31+
final static Set<Class> WITH_CAPACITY_COLLECTION_CLASSES = new HashSet<Class>(){{
32+
add(ArrayList.class);
33+
add(HashSet.class);
34+
}};
3135
static volatile Map<String, Decoder> cache = new HashMap<>();
3236
static ClassPool pool = ClassPool.getDefault();
3337

@@ -52,18 +56,7 @@ private synchronized static Decoder gen(String cacheKey, Type type, Type[] typeA
5256
} else {
5357
clazz = (Class) type;
5458
}
55-
String source;
56-
if (clazz.isArray()) {
57-
source = genArray(clazz);
58-
} else if (List.class.isAssignableFrom(clazz)) {
59-
Class compType = (Class) typeArgs[0];
60-
if (clazz == List.class) {
61-
clazz = ArrayList.class;
62-
}
63-
source = genList(clazz, compType);
64-
} else {
65-
source = genObject(clazz, cacheKey);
66-
}
59+
String source = genSource(cacheKey, typeArgs, clazz);
6760
try {
6861
CtClass ctClass = pool.makeClass(cacheKey);
6962
ctClass.setInterfaces(new CtClass[]{pool.get(Decoder.class.getName())});
@@ -79,6 +72,26 @@ private synchronized static Decoder gen(String cacheKey, Type type, Type[] typeA
7972
}
8073
}
8174

75+
private static String genSource(String cacheKey, Type[] typeArgs, Class clazz) {
76+
if (clazz.isArray()) {
77+
return genArray(clazz);
78+
} else if (Collection.class.isAssignableFrom(clazz)) {
79+
Class compType = (Class) typeArgs[0];
80+
if (clazz == List.class) {
81+
clazz = ArrayList.class;
82+
} else if (clazz == Set.class) {
83+
clazz = HashSet.class;
84+
}
85+
if (WITH_CAPACITY_COLLECTION_CLASSES.contains(clazz)) {
86+
return genCollectionWithCapacity(clazz, compType);
87+
} else {
88+
return genCollection(clazz, compType);
89+
}
90+
} else {
91+
return genObject(clazz, cacheKey);
92+
}
93+
}
94+
8295
public static void addNewDecoder(String cacheKey, Decoder decoder) {
8396
HashMap<String, Decoder> newCache = new HashMap<>(cache);
8497
newCache.put(cacheKey, decoder);
@@ -224,7 +237,57 @@ private static String genArray(Class clazz) {
224237
"{{op}}", op);
225238
}
226239

227-
private static String genList(Class clazz, Class compType) {
240+
private static String genCollectionWithCapacity(Class clazz, Class compType) {
241+
String nativeRead = NATIVE_READS.get(compType.getName());
242+
StringBuilder lines = new StringBuilder();
243+
append(lines, "public Object decode(java.lang.reflect.Type type, com.github.jsoniter.Jsoniter iter) {");
244+
append(lines, "if (!iter.readArray()) {");
245+
append(lines, "return new {{clazz}}(0);");
246+
append(lines, "}");
247+
append(lines, "{{comp}} a1 = ({{comp}}) {{op}};");
248+
append(lines, "if (!iter.readArray()) {");
249+
append(lines, "{{clazz}} obj = new {{clazz}}(1);");
250+
append(lines, "obj.add(a1);");
251+
append(lines, "return obj;");
252+
append(lines, "}");
253+
append(lines, "{{comp}} a2 = ({{comp}}) {{op}};");
254+
append(lines, "if (!iter.readArray()) {");
255+
append(lines, "{{clazz}} obj = new {{clazz}}(2);");
256+
append(lines, "obj.add(a1);");
257+
append(lines, "obj.add(a2);");
258+
append(lines, "return obj;");
259+
append(lines, "}");
260+
append(lines, "{{comp}} a3 = ({{comp}}) {{op}};");
261+
append(lines, "if (!iter.readArray()) {");
262+
append(lines, "{{clazz}} obj = new {{clazz}}(3);");
263+
append(lines, "obj.add(a1);");
264+
append(lines, "obj.add(a2);");
265+
append(lines, "obj.add(a3);");
266+
append(lines, "return obj;");
267+
append(lines, "}");
268+
append(lines, "{{comp}} a4 = ({{comp}}) {{op}};");
269+
append(lines, "{{clazz}} obj = new {{clazz}}(8);");
270+
append(lines, "obj.add(a1);");
271+
append(lines, "obj.add(a2);");
272+
append(lines, "obj.add(a3);");
273+
append(lines, "obj.add(a4);");
274+
append(lines, "int i = 4;");
275+
append(lines, "while (iter.readArray()) {");
276+
append(lines, "obj.add(({{comp}}) {{op}});");
277+
append(lines, "}");
278+
append(lines, "return obj;");
279+
append(lines, "}");
280+
String op = String.format("iter.read(%s.class)", compType.getCanonicalName());
281+
if (nativeRead != null) {
282+
op = nativeRead;
283+
}
284+
return lines.toString().replace(
285+
"{{clazz}}", clazz.getName()).replace(
286+
"{{comp}}", compType.getCanonicalName()).replace(
287+
"{{op}}", op);
288+
}
289+
290+
private static String genCollection(Class clazz, Class compType) {
228291
String nativeRead = NATIVE_READS.get(compType.getName());
229292
StringBuilder lines = new StringBuilder();
230293
append(lines, "public Object decode(java.lang.reflect.Type type, com.github.jsoniter.Jsoniter iter) {");

test/main/java/com/github/jsoniter/TestReflection.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
import java.io.IOException;
66
import java.util.ArrayList;
7+
import java.util.HashSet;
78
import java.util.List;
9+
import java.util.Set;
810

911
import static org.junit.Assert.assertArrayEquals;
1012

@@ -40,6 +42,12 @@ public void test_string_list() throws IOException {
4042
assertArrayEquals(new String[]{"hello", "world"}, val.toArray(new String[0]));
4143
}
4244

45+
public void test_string_set() throws IOException {
46+
Jsoniter iter = Jsoniter.parse("['hello']".replace('\'', '"'));
47+
Set<String> val = iter.read(new TypeLiteral<Set<String>>(){});
48+
assertArrayEquals(new String[]{"hello"}, val.toArray(new String[0]));
49+
}
50+
4351
public void test_float_array() throws IOException {
4452
Jsoniter iter = Jsoniter.parse("[1.1,2,3]");
4553
float[] val = iter.read(float[].class);

0 commit comments

Comments
 (0)