001/* 002 * Copyright (c) 2015-2020, Oracle and/or its affiliates. All rights reserved. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.tribuo.util.infotheory.impl; 018 019import com.oracle.labs.mlrg.olcut.util.Pair; 020 021import java.util.ArrayList; 022 023/** 024 * A pair of things with a cached hashcode. 025 * <p> 026 * The cache is calculated on construction, and the objects inside the pair are thus expected to be immutable. 027 * If they aren't then the behaviour is undefined (and you shouldn't use this class). 028 * @param <T1> The type of the first object. 029 * @param <T2> The type of the second object. 030 */ 031public class CachedPair<T1, T2> extends Pair<T1,T2> { 032 private static final long serialVersionUID = 1L; 033 034 private final int cachedHash; 035 036 /** 037 * Constructs a CachedPair. 038 * @param a The first element. 039 * @param b The second element. 040 */ 041 public CachedPair(T1 a, T2 b) { 042 super(a,b); 043 this.cachedHash = super.hashCode(); 044 } 045 046 /** 047 * Takes two arrays and zips them together into an array of CachedPairs. 048 * @param <T1> The type contained in the first array. 049 * @param <T2> The type contained in the second array. 050 * @param first An array of values. 051 * @param second Another array of values. 052 * @return The zipped array. 053 */ 054 public static <T1,T2> ArrayList<CachedPair<T1,T2>> zipArraysCached(ArrayList<T1> first, ArrayList<T2> second) { 055 if (first.size() == second.size()) { 056 ArrayList<CachedPair<T1,T2>> output = new ArrayList<>(first.size()); 057 058 for (int i = 0; i < first.size(); i++) { 059 CachedPair<T1,T2> pair = new CachedPair<>(first.get(i),second.get(i)); 060 output.add(i, pair); 061 } 062 063 return output; 064 } else { 065 throw new IllegalArgumentException("Zipping requires arrays of the same length. first.size() = " + first.size() + ", second.size() = " + second.size()); 066 } 067 } 068 069 /** 070 * Overridden hashcode. 071 * Uses the cached value calculated on construction. 072 * @return A 32-bit integer. 073 */ 074 @Override 075 public int hashCode() { 076 return cachedHash; 077 } 078 079 @Override 080 public boolean equals(Object o) { 081 if (this == o) return true; 082 if (o == null || getClass() != o.getClass()) return false; 083 if (!super.equals(o)) return false; 084 CachedPair<?, ?> that = (CachedPair<?, ?>) o; 085 return cachedHash == that.cachedHash; 086 } 087}