Implement equals and hashCode in ParameterizedTypeImpl

and GenericArrayTypeImpl.

Bug: 14590652
Bug: https://code.google.com/p/android/issues/detail?id=74060

(cherry picked from commit c7dede2138e5b122cb1011a355e4f9f8e6d37856)

Change-Id: I5b95f816e0596ca6f51dce5959433dc70b2c297d
diff --git a/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java b/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java
index ef22576..5919a19 100644
--- a/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java
+++ b/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java
@@ -18,6 +18,7 @@
 
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.Type;
+import java.util.Objects;
 
 public final class GenericArrayTypeImpl implements GenericArrayType {
     private final Type componentType;
@@ -34,6 +35,20 @@
         }
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof GenericArrayType)) {
+            return false;
+        }
+        GenericArrayType that = (GenericArrayType) o;
+        return Objects.equals(getGenericComponentType(), that.getGenericComponentType());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(getGenericComponentType());
+    }
+
     public String toString() {
         return componentType.toString() + "[]";
     }
diff --git a/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java b/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java
index 99dfe8b..2cd5ac3 100644
--- a/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java
+++ b/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java
@@ -18,17 +18,22 @@
 
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Objects;
 
 public final class ParameterizedTypeImpl implements ParameterizedType {
     private final ListOfTypes args;
     private final ParameterizedTypeImpl ownerType0; // Potentially unresolved.
-    private Type ownerTypeRes;
-    private Class rawType; // Already resolved.
+    private Type ownerTypeRes; // Potentially unresolved.
+    private Class rawType; // Potentially unresolved.
     private final String rawTypeName;
-    private ClassLoader loader;
+    private final ClassLoader loader;
 
     public ParameterizedTypeImpl(ParameterizedTypeImpl ownerType, String rawTypeName,
             ListOfTypes args, ClassLoader loader) {
+        if (args == null) {
+            throw new NullPointerException();
+        }
         this.ownerType0 = ownerType;
         this.rawTypeName = rawTypeName;
         this.args = args;
@@ -37,7 +42,6 @@
 
 
     public Type[] getActualTypeArguments() {
-        // ASSUMPTION: args is never null!!!
         return args.getResolvedTypes().clone();
     }
 
@@ -76,6 +80,23 @@
     }
 
     @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof ParameterizedType)) {
+            return false;
+        }
+        ParameterizedType that = (ParameterizedType) o;
+        return Objects.equals(getRawType(), that.getRawType()) &&
+                Objects.equals(getOwnerType(), that.getOwnerType()) &&
+                Arrays.equals(args.getResolvedTypes(), that.getActualTypeArguments());
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * (31 * Objects.hashCode(getRawType()) + Objects.hashCode(getOwnerType())) +
+            Arrays.hashCode(args.getResolvedTypes());
+    }
+
+    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append(rawTypeName);