001 // Copyright 2006 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.internal.util;
016
017 import java.util.Arrays;
018
019 /**
020 * Combines multiple values to form a single composite key. MultiKey can often be used as an alternative to nested
021 * maps.
022 */
023 public final class MultiKey
024 {
025 private static final int PRIME = 31;
026
027 private final Object[] values;
028
029 private final int hashCode;
030
031 /**
032 * Creates a new instance from the provided values. It is assumed that the values provided are good map keys
033 * themselves -- immutable, with proper implementations of equals() and hashCode().
034 *
035 * @param values
036 */
037 public MultiKey(Object... values)
038 {
039 this.values = values;
040
041 hashCode = PRIME * Arrays.hashCode(this.values);
042 }
043
044 @Override
045 public int hashCode()
046 {
047 return hashCode;
048 }
049
050 @Override
051 public boolean equals(Object obj)
052 {
053 if (this == obj)
054 return true;
055 if (obj == null)
056 return false;
057 if (getClass() != obj.getClass())
058 return false;
059 final MultiKey other = (MultiKey) obj;
060
061 return Arrays.equals(values, other.values);
062 }
063
064 @Override
065 public String toString()
066 {
067 StringBuilder builder = new StringBuilder("MultiKey[");
068
069 boolean first = true;
070
071 for (Object o : values)
072 {
073 if (!first)
074 builder.append(", ");
075
076 builder.append(o);
077
078 first = false;
079 }
080
081 builder.append("]");
082
083 return builder.toString();
084 }
085
086 }