resolve conflict in readme
diff --git a/README.md b/README.md
index 349777b..8f96e36 100644
--- a/README.md
+++ b/README.md
@@ -222,6 +222,40 @@
  00000040  0c 30 31 30 2d 31 32 33  34 35 36 37 38           |.010-12345678|
 ```
 
+#### Using Java collections
+By default, the output of Hessian Java impl of a Java collection like java.util.HashSet will be decoded as `[]interface{}` in `go-hessian2`.
+To apply the one-to-one mapping relationship between certain Java collection class and your Go struct, examples are as follows:
+
+```go
+//use HashSet as example
+//define your struct, which should implements hessian.JavaCollectionObject
+type JavaHashSet struct {
+	value []interface{}
+}
+
+//get the inside slice value
+func (j *JavaHashSet) Get() []interface{} {
+	return j.value
+}
+
+//set the inside slice value
+func (j *JavaHashSet) Set(v []interface{}) {
+	j.value = v
+}
+
+//should be the same as the class name of the Java collection 
+func (j *JavaHashSet) JavaClassName() string {
+	return "java.util.HashSet"
+}
+
+func init() {
+        //register your struct so that hessian can recognized it when encoding and decoding 
+	SetCollectionSerialize(&JavaHashSet{})
+}
+```
+
+
+
 ## Notice for inheritance
 
 `go-hessian2` supports inheritance struct, but the following situations should be avoided.
diff --git a/java_collection.go b/java_collection.go
new file mode 100644
index 0000000..93ed4e6
--- /dev/null
+++ b/java_collection.go
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package hessian
+
+import (
+	perrors "github.com/pkg/errors"
+	"reflect"
+)
+
+type JavaCollectionObject interface {
+	Get() []interface{}
+	Set([]interface{})
+	JavaClassName() string
+}
+
+var collectionTypeMap = make(map[string]reflect.Type, 16)
+
+func SetCollectionSerialize(collection JavaCollectionObject) {
+	name := collection.JavaClassName()
+	v := reflect.ValueOf(collection)
+	var typ reflect.Type
+	switch v.Kind() {
+	case reflect.Struct:
+		typ = v.Type()
+	case reflect.Ptr:
+		typ = v.Elem().Type()
+	default:
+		typ = reflect.TypeOf(collection)
+	}
+	SetSerializer(name, JavaCollectionSerializer{})
+	RegisterPOJO(collection)
+	collectionTypeMap[name] = typ
+}
+
+func getCollectionSerialize(name string) reflect.Type {
+	return collectionTypeMap[name]
+}
+
+func isCollectionSerialize(name string) bool {
+	return getCollectionSerialize(name) != nil
+}
+
+type JavaCollectionSerializer struct {
+}
+
+func (JavaCollectionSerializer) EncObject(e *Encoder, vv POJO) error {
+	var (
+		err error
+	)
+	v, ok := vv.(JavaCollectionObject)
+	if !ok {
+		return perrors.New("can not be converted into java collection object")
+	}
+	collectionName := v.JavaClassName()
+	if collectionName == "" {
+		return perrors.New("collection name empty")
+	}
+	list := v.Get()
+	length := len(list)
+	typeName := v.JavaClassName()
+	err = writeCollectionBegin(length, typeName, e)
+	if err != nil {
+		return err
+	}
+	for i := 0; i < length; i++ {
+		if err = e.Encode(list[i]); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (JavaCollectionSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+	//for the java impl of hessian encode collections as list, which will not be decoded as object in go impl, this method should not be called
+	return nil, perrors.New("unexpected collection decode call")
+}
+
+func (d *Decoder) decodeCollection(length int, listTyp string) (interface{}, error) {
+	typ := getCollectionSerialize(listTyp)
+	if typ == nil {
+		return nil, perrors.New("no collection deserialize set as " + listTyp)
+	}
+	v := reflect.New(typ).Interface()
+	collcetionV, ok := v.(JavaCollectionObject)
+	if !ok {
+		return nil, perrors.New("collection deserialize err " + listTyp)
+	}
+	list, err := d.readTypedListValue(length, "", false)
+	if err != nil {
+		return nil, err
+	}
+	listInterface, err := EnsureInterface(list, nil)
+	if err != nil {
+		return nil, err
+	}
+	listV, listOk := listInterface.([]interface{})
+	if !listOk {
+		return nil, perrors.New("collection deserialize err " + listTyp)
+	}
+	collcetionV.Set(listV)
+	return collcetionV, nil
+}
+
+func writeCollectionBegin(length int, typeName string, e *Encoder) error {
+	var err error
+	if length <= int(LIST_DIRECT_MAX) {
+		e.Append([]byte{BC_LIST_DIRECT + byte(length)})
+		err = e.Encode(typeName)
+		if err != nil {
+			return err
+		}
+	} else {
+		e.Append([]byte{BC_LIST_FIXED})
+		err = e.Encode(typeName)
+		if err != nil {
+			return err
+		}
+		err = e.Encode(int32(length))
+		if err != nil {
+			return nil
+		}
+	}
+	return nil
+}
diff --git a/java_collection_test.go b/java_collection_test.go
new file mode 100644
index 0000000..875eb9b
--- /dev/null
+++ b/java_collection_test.go
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package hessian
+
+import (
+	"testing"
+)
+
+func init() {
+	SetCollectionSerialize(&JavaHashSet{})
+}
+
+type JavaHashSet struct {
+	value []interface{}
+}
+
+func (j *JavaHashSet) Get() []interface{} {
+	return j.value
+}
+
+func (j *JavaHashSet) Set(v []interface{}) {
+	j.value = v
+}
+
+func (j *JavaHashSet) JavaClassName() string {
+	return "java.util.HashSet"
+}
+
+func TestListJavaCollectionEncode(t *testing.T) {
+	inside := make([]interface{}, 2)
+	inside[0] = int32(0)
+	inside[1] = int32(1)
+	hashSet := JavaHashSet{value: inside}
+	testJavaDecode(t, "customArgTypedFixedList_HashSet", &hashSet)
+}
+
+func TestListJavaCollectionDecode(t *testing.T) {
+	inside := make([]interface{}, 2)
+	inside[0] = int32(0)
+	inside[1] = int32(1)
+	hashSet := JavaHashSet{value: inside}
+	testDecodeFramework(t, "customReplyTypedFixedList_HashSet", &hashSet)
+}
diff --git a/list.go b/list.go
index bd330c9..34c8aec 100644
--- a/list.go
+++ b/list.go
@@ -311,7 +311,13 @@
 	} else {
 		return nil, perrors.Errorf("error typed list tag: 0x%x", tag)
 	}
+	if isCollectionSerialize(listTyp) {
+		return d.decodeCollection(length, listTyp)
+	}
+	return d.readTypedListValue(length, listTyp, isVariableArr)
+}
 
+func (d *Decoder) readTypedListValue(length int, listTyp string, isVariableArr bool) (interface{}, error) {
 	// return when no element
 	if length < 0 {
 		return nil, nil
diff --git a/test_hessian/src/main/java/test/TestCustomDecode.java b/test_hessian/src/main/java/test/TestCustomDecode.java
index f06fc99..e2394f5 100644
--- a/test_hessian/src/main/java/test/TestCustomDecode.java
+++ b/test_hessian/src/main/java/test/TestCustomDecode.java
@@ -23,10 +23,8 @@
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
+
 import test.model.DateDemo;
 
 
@@ -201,4 +199,9 @@
         String o = (String) input.readObject();
         return TestString.getEmojiTestString().equals(o);
     }
+
+    public Object customArgTypedFixedList_HashSet() throws Exception {
+        HashSet o = (HashSet) input.readObject();
+        return o.contains(0) && o.contains(1);
+    }
 }
\ No newline at end of file
diff --git a/test_hessian/src/main/java/test/TestCustomReply.java b/test_hessian/src/main/java/test/TestCustomReply.java
index a907150..813d7eb 100644
--- a/test_hessian/src/main/java/test/TestCustomReply.java
+++ b/test_hessian/src/main/java/test/TestCustomReply.java
@@ -26,6 +26,9 @@
 import java.math.BigInteger;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
 import test.model.DateDemo;
 
 
@@ -437,6 +440,22 @@
         output.writeObject(dog);
         output.flush();
     }
+
+    public void customReplyTypedFixedList_HashSet() throws Exception {
+        Set<Integer> set = new HashSet<>();
+        set.add(0);
+        set.add(1);
+        output.writeObject(set);
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_HashSetCustomObject() throws Exception {
+        Set<Object> set = new HashSet<>();
+        set.add(new BigInteger("1234"));
+        set.add(new BigDecimal("123.4"));
+        output.writeObject(set);
+        output.flush();
+    }
 }
 
 interface Leg {