001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.util.pair; 031 032import java.util.ArrayList; 033import java.util.List; 034 035import org.openimaj.util.function.Function; 036 037/** 038 * {@link IndependentPair} represents a generic pair of objects of different 039 * (independent) types. 040 * 041 * @author Jonathon Hare 042 * 043 * @param <A> 044 * the class of the first object in the pair 045 * @param <B> 046 * the class of the second object in the pair 047 */ 048public class IndependentPair<A, B> { 049 050 A o1; 051 B o2; 052 053 /** 054 * Constructs a Pair object with two objects obj1 and obj2 055 * 056 * @param obj1 057 * first object in pair 058 * @param obj2 059 * second objec in pair 060 */ 061 public IndependentPair(final A obj1, final B obj2) 062 { 063 this.o1 = obj1; 064 this.o2 = obj2; 065 } 066 067 /** 068 * @return first object in pair 069 */ 070 public A firstObject() 071 { 072 return this.o1; 073 } 074 075 /** 076 * @return second object in pair 077 */ 078 public B secondObject() 079 { 080 return this.o2; 081 } 082 083 /** 084 * @return first object in pair 085 */ 086 public A getFirstObject() 087 { 088 return this.o1; 089 } 090 091 /** 092 * @return second object in pair 093 */ 094 public B getSecondObject() 095 { 096 return this.o2; 097 } 098 099 /** 100 * Set first object in pair to obj 101 * 102 * @param obj 103 * the object 104 */ 105 public void setFirstObject(final A obj) 106 { 107 this.o1 = obj; 108 } 109 110 /** 111 * Set second object in pair to obj 112 * 113 * @param obj 114 * the object 115 */ 116 public void setSecondObject(final B obj) 117 { 118 this.o2 = obj; 119 } 120 121 @Override 122 public String toString() { 123 return "[" + this.o1 + "," + this.o2 + "]"; 124 } 125 126 @Override 127 public boolean equals(final Object thatObject) { 128 if (!(thatObject instanceof IndependentPair)) 129 return false; 130 @SuppressWarnings("rawtypes") 131 final IndependentPair that = (IndependentPair) thatObject; 132 return this.o1 == that.o1 && this.o2 == that.o2; 133 } 134 135 /** 136 * Create a pair from the given objects. 137 * 138 * @param <T> 139 * Type of first object. 140 * @param <Q> 141 * Type of second object. 142 * @param t 143 * The first object. 144 * @param q 145 * The second object. 146 * @return The pair. 147 */ 148 public static <T, Q> IndependentPair<T, Q> pair(final T t, final Q q) { 149 return new IndependentPair<T, Q>(t, q); 150 } 151 152 /** 153 * Extract the first objects from a list of pairs. 154 * 155 * @param <T> 156 * type of first object 157 * @param <Q> 158 * type of second object 159 * @param data 160 * the data 161 * @return extracted first objects 162 */ 163 public static <T, Q> List<T> getFirst(final Iterable<? extends IndependentPair<T, Q>> data) { 164 final List<T> extracted = new ArrayList<T>(); 165 166 for (final IndependentPair<T, Q> item : data) 167 extracted.add(item.o1); 168 169 return extracted; 170 } 171 172 /** 173 * Extract the second objects from a list of pairs. 174 * 175 * @param <T> 176 * type of first object 177 * @param <Q> 178 * type of second object 179 * @param data 180 * the data 181 * @return extracted second objects 182 */ 183 public static <T, Q> List<Q> getSecond(final Iterable<? extends IndependentPair<T, Q>> data) { 184 final List<Q> extracted = new ArrayList<Q>(); 185 186 for (final IndependentPair<T, Q> item : data) 187 extracted.add(item.o2); 188 189 return extracted; 190 } 191 192 /** 193 * Get the function that returns the first object from the pair 194 * 195 * @return the function that returns the first object from the pair 196 */ 197 public static <T, Q> Function<IndependentPair<T, Q>, T> getFirstFunction() { 198 return new Function<IndependentPair<T, Q>, T>() { 199 @Override 200 public T apply(IndependentPair<T, Q> in) { 201 return in.o1; 202 } 203 204 }; 205 } 206 207 /** 208 * Get the function that returns the second object from the pair 209 * 210 * @return the function that returns the second object from the pair 211 */ 212 public static <T, Q> Function<IndependentPair<T, Q>, Q> getSecondFunction() { 213 return new Function<IndependentPair<T, Q>, Q>() { 214 @Override 215 public Q apply(IndependentPair<T, Q> in) { 216 return in.o2; 217 } 218 }; 219 } 220 221 /** 222 * Create a pair list from the given objects. 223 * 224 * @param <T> 225 * Type of objects. 226 * @param t 227 * The list of first objects. 228 * @param q 229 * The list of second objects. 230 * @return The list of pairs. 231 */ 232 public static <T, Q> List<IndependentPair<T, Q>> pairList(final List<T> t, final List<Q> q) { 233 final List<IndependentPair<T, Q>> list = new ArrayList<IndependentPair<T, Q>>(t.size()); 234 235 for (int i = 0; i < t.size(); i++) { 236 list.add(new IndependentPair<T, Q>(t.get(i), q.get(i))); 237 } 238 239 return list; 240 } 241 242 /** 243 * Create a new {@link IndependentPair} from this one with the elements 244 * swapped 245 * 246 * @return the swapped pair 247 */ 248 public IndependentPair<B, A> swap() { 249 return new IndependentPair<B, A>(o2, o1); 250 } 251 252 /** 253 * Swap the order of the pairs 254 * 255 * @param data 256 * the input 257 * @return the swapped data 258 */ 259 public static <T, Q> List<IndependentPair<? extends Q, ? extends T>> swapList( 260 List<? extends IndependentPair<? extends T, ? extends Q>> data) 261 { 262 final List<IndependentPair<? extends Q, ? extends T>> list = new ArrayList<IndependentPair<? extends Q, ? extends T>>( 263 data.size()); 264 265 for (int i = 0; i < data.size(); i++) { 266 list.add(data.get(i).swap()); 267 } 268 269 return list; 270 } 271}