releng: Transition to jdt.annotation 2.0
[deliverable/tracecompass.git] / common / org.eclipse.tracecompass.common.core / src / org / eclipse / tracecompass / common / core / ObjectUtils.java
CommitLineData
ac1d454a
PT
1/*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.common.core;
14
15import java.lang.reflect.Array;
16import java.util.Collection;
17import java.util.Iterator;
18import java.util.Set;
19import java.util.SortedSet;
20
21import org.eclipse.jdt.annotation.Nullable;
22
23/**
24 * Utility methods for arbitrary objects.
25 *
26 * @author Patrick Tasse
4c4e2816 27 * @since 2.0
ac1d454a
PT
28 */
29public final class ObjectUtils {
30
31 private ObjectUtils() {}
32
33 /**
34 * Checks deep equality of two objects that may be arrays or collections.
35 * The objects (and each of their respective elements, if applicable) must
36 * be of the same class to be considered equal. Deep equality is recursively
37 * called on each element of an array or collection, if applicable.
38 *
39 * @param o1
40 * the first object to compare
41 * @param o2
42 * the second object to compare
43 * @return true if the objects are deeply equal, false otherwise
44 */
45 public static boolean deepEquals(final @Nullable Object o1, @Nullable final Object o2) {
46 if (o1 == o2) {
47 return true;
48 }
49 if (o1 == null || o2 == null) {
50 return false;
51 }
52 Class<?> class1 = o1.getClass();
53 Class<?> class2 = o2.getClass();
54 if (!class1.equals(class2)) {
55 return false;
56 }
57 if (class1.isArray()) {
58 int length = Array.getLength(o1);
59 if (Array.getLength(o2) != length) {
60 return false;
61 }
62 for (int i = 0; i < length; i++) {
63 if (!deepEquals(Array.get(o1, i), Array.get(o2, i))) {
64 return false;
65 }
66 }
67 return true;
68 } else if (o1 instanceof Collection) {
69 Collection<?> c1 = (Collection<?>) o1;
70 Collection<?> c2 = (Collection<?>) o2;
71 int size = c1.size();
72 if (c2.size() != size) {
73 return false;
74 }
75 if (o1 instanceof Set && !(o1 instanceof SortedSet<?>)) {
76 /* Iteration order is undefined */
77 for (Object e1 : c1) {
78 boolean contains = false;
79 for (Object e2 : c2) {
80 if (deepEquals(e1, e2)) {
81 contains = true;
82 break;
83 }
84 }
85 if (!contains) {
86 return false;
87 }
88 }
89 return true;
90 }
91 Iterator<?> i1 = c1.iterator();
92 Iterator<?> i2 = c2.iterator();
93 while (i1.hasNext()) {
94 if (!deepEquals(i1.next(), i2.next())) {
95 return false;
96 }
97 }
98 return true;
99 }
100 return o1.equals(o2);
101 }
102
103 /**
104 * Returns a hash code value for an object which may be an array or a
105 * collection. The deep hash code is recursively computed for each element
106 * of an array or collection, if applicable.
107 *
108 * @param o
109 * the object
110 * @return a hash code value for this object.
111 */
112 public static int deepHashCode(final @Nullable Object o) {
113 if (o == null) {
114 return 0;
115 }
116 if (o.getClass().isArray()) {
117 final int prime = 31;
118 int result = 1;
119 for (int i = 0; i < Array.getLength(o); i++) {
120 result = prime * result + deepHashCode(Array.get(o, i));
121 }
122 return result;
123 }
124 if (o instanceof Collection) {
125 Collection<?> c = (Collection<?>) o;
126 if (o instanceof Set && !(o instanceof SortedSet<?>)) {
127 /* Iteration order is undefined */
128 int result = 0;
129 for (Object e : c) {
130 result += deepHashCode(e);
131 }
132 return result;
133 }
134 final int prime = 31;
135 int result = 1;
136 for (Object e : c) {
137 result = prime * result + deepHashCode(e);
138 }
139 return result;
140 }
141 return o.hashCode();
142 }
143}
This page took 0.030036 seconds and 5 git commands to generate.