001package net.gdface.utils; 002 003import java.lang.reflect.Array; 004import java.lang.reflect.ParameterizedType; 005import java.lang.reflect.Type; 006import java.net.MalformedURLException; 007import java.net.URI; 008import java.net.URL; 009import java.nio.ByteBuffer; 010import java.util.Arrays; 011import java.util.Date; 012import java.util.List; 013import java.util.Map; 014import java.util.Map.Entry; 015import java.util.Set; 016 017import com.google.common.base.Function; 018import com.google.common.collect.HashBasedTable; 019import com.google.common.collect.ImmutableMap; 020import com.google.common.collect.Iterables; 021import com.google.common.collect.Lists; 022import com.google.common.collect.Maps; 023import com.google.common.collect.Maps.EntryTransformer; 024import com.google.common.collect.Sets; 025import com.google.common.collect.Table; 026import com.google.common.primitives.Booleans; 027import com.google.common.primitives.Doubles; 028import com.google.common.primitives.Floats; 029import com.google.common.primitives.Ints; 030import com.google.common.primitives.Longs; 031import com.google.common.primitives.Shorts; 032import com.google.common.reflect.TypeToken; 033 034import static com.google.common.base.Preconditions.*; 035/** 036 * 类型转æ¢å·¥å…·ç±» 037 * @author guyadong 038 * 039 */ 040public class BaseTypeTransformer { 041 /** 042 * 返回buffer䏿‰€æœ‰å—节(position~limit),䏿”¹å˜bufferçŠ¶æ€ 043 * @param buffer 044 * @return buffer 为 null 时返回 null 045 */ 046 public static final byte[] getBytesInBuffer(ByteBuffer buffer){ 047 if(null == buffer){ 048 return null; 049 } 050 int pos = buffer.position(); 051 try{ 052 byte[] bytes = new byte[buffer.remaining()]; 053 buffer.get(bytes); 054 return bytes; 055 }finally{ 056 buffer.position(pos); 057 } 058 } 059 @SuppressWarnings("rawtypes") 060 private final Function sameTypeFun = new Function(){ 061 @Override 062 public Object apply(Object input) { 063 return input; 064 }}; 065 private final Function<Boolean,Boolean> booleanTypeFun = new Function<Boolean,Boolean>(){ 066 @Override 067 public Boolean apply(Boolean input) { 068 return checkNotNull(input,"input is null").booleanValue(); 069 }}; 070 private final Function<Character,Character> charTypeFun = new Function<Character,Character>(){ 071 @Override 072 public Character apply(Character input) { 073 return checkNotNull(input,"input is null").charValue(); 074 }}; 075 private final Function<Byte,Byte> byteTypeFun = new Function<Byte,Byte>(){ 076 @Override 077 public Byte apply(Byte input) { 078 return checkNotNull(input,"input is null").byteValue(); 079 }}; 080 private final Function<Short,Short> shortTypeFun = new Function<Short,Short>(){ 081 @Override 082 public Short apply(Short input) { 083 return checkNotNull(input,"input is null").shortValue(); 084 }}; 085 private final Function<Integer,Integer> intTypeFun = new Function<Integer,Integer>(){ 086 @Override 087 public Integer apply(Integer input) { 088 return checkNotNull(input,"input is null").intValue(); 089 }}; 090 private final Function<Long,Long> longTypeFun = new Function<Long,Long>(){ 091 @Override 092 public Long apply(Long input) { 093 return checkNotNull(input,"input is null").longValue(); 094 }}; 095 private final Function<Float,Float> floatTypeFun = new Function<Float,Float>(){ 096 @Override 097 public Float apply(Float input) { 098 return checkNotNull(input,"input is null").floatValue(); 099 }}; 100 private final Function<Double,Double> doubleTypeFun = new Function<Double,Double>(){ 101 @Override 102 public Double apply(Double input) { 103 Double.class.isPrimitive(); 104 return checkNotNull(input,"input is null").doubleValue(); 105 }}; 106 private final Function<Void,Void> voidTypeFun = new Function<Void,Void>(){ 107 @Override 108 public Void apply(Void input) { 109 return null; 110 }}; 111 private final Function<byte[],ByteBuffer> byteArray2ByteBufferFun = new Function<byte[],ByteBuffer>(){ 112 @Override 113 public ByteBuffer apply(byte[] input) { 114 return null == input ? null :ByteBuffer.wrap(input); 115 }}; 116 private final Function<ByteBuffer,byte[]> byteBuffer2ByteArrayFun = new Function<ByteBuffer,byte[]>(){ 117 @Override 118 public byte[] apply(ByteBuffer input) { 119 return getBytesInBuffer(input); 120 }}; 121 private final Function<Float,Double> float2DoubleFun = new Function<Float,Double>(){ 122 @Override 123 public Double apply(Float input) { 124 return null == input ? null : input.doubleValue(); 125 }}; 126 private final Function<Double,Float> double2FloatFun = new Function<Double,Float>(){ 127 @Override 128 public Float apply(Double input) { 129 return null == input ? null : input.floatValue(); 130 }}; 131 private final Function<Date,Long> date2LongFunction = new Function<Date,Long>(){ 132 @Override 133 public Long apply(Date input) { 134 return null == input ? null : input.getTime(); 135 }}; 136 private final Function<Long,Date> long2DateFun = new Function<Long,Date>(){ 137 @Override 138 public Date apply(Long input) { 139 return null == input ? null : new Date(input); 140 }}; 141 private final Function<Long,java.sql.Date> long2SqlDateFun = new Function<Long,java.sql.Date>(){ 142 @Override 143 public java.sql.Date apply(Long input) { 144 return null == input ? null : new java.sql.Date(input); 145 }}; 146 private final Function<Long,java.sql.Time> long2SqlTimeFun = new Function<Long,java.sql.Time>(){ 147 @Override 148 public java.sql.Time apply(Long input) { 149 return null == input ? null : new java.sql.Time(input); 150 }}; 151 private final Function<URL,String> url2StringFun = new Function<URL,String>(){ 152 @Override 153 public String apply(URL input) { 154 return null == input ? null : input.toString(); 155 }}; 156 private final Function<URI,String> uri2StringFun = new Function<URI,String>(){ 157 @Override 158 public String apply(URI input) { 159 return null == input ? null : input.toString(); 160 }}; 161 private final Function<String,URL> string2UrlFun = new Function<String,URL>(){ 162 @Override 163 public URL apply(String input) { 164 try { 165 return null == input ? null : new URL(input); 166 } catch (MalformedURLException e) { 167 throw new RuntimeException(e); 168 } 169 }}; 170 private final Function<String,URI> string2UriFun = new Function<String,URI>(){ 171 @Override 172 public URI apply(String input) { 173 return null == input ? null : URI.create(input); 174 }}; 175 private final Function<int[],List<Integer>> intArray2List = new Function<int[],List<Integer>>(){ 176 @Override 177 public List<Integer> apply(int[] input) { 178 return null == input ? null : Ints.asList(input); 179 }}; 180 private final Function<long[],List<Long>> longArray2List = new Function<long[],List<Long>>(){ 181 @Override 182 public List<Long> apply(long[] input) { 183 return null == input ? null : Longs.asList(input); 184 }}; 185 private final Function<double[],List<Double>> doubleArray2List = new Function<double[],List<Double>>(){ 186 @Override 187 public List<Double> apply(double[] input) { 188 return null == input ? null : Doubles.asList(input); 189 }}; 190 private final Function<float[],List<Double>> floatArray2List = new Function<float[],List<Double>>(){ 191 @Override 192 public List<Double> apply(float[] input) { 193 return null == input 194 ? null 195 : Lists.transform(Floats.asList(input),(Function<Float,Double>)float2DoubleFun); 196 }}; 197 private final Function<short[],List<Short>> shortArray2List = new Function<short[],List<Short>>(){ 198 @Override 199 public List<Short> apply(short[] input) { 200 return null == input ? null : Shorts.asList(input); 201 }}; 202 private final Function<boolean[],List<Boolean>> booleanArray2List = new Function<boolean[],List<Boolean>>(){ 203 @Override 204 public List<Boolean> apply(boolean[] input) { 205 return null == input ? null : Booleans.asList(input); 206 }}; 207 private final Function<List<Integer>,int[]> list2intArray = new Function<List<Integer>,int[]>(){ 208 @Override 209 public int[] apply(List<Integer> input) { 210 return null == input ? null : Ints.toArray(input); 211 }}; 212 private final Function<List<Long>,long[]> list2longArray = new Function<List<Long>,long[]>(){ 213 @Override 214 public long[] apply(List<Long> input) { 215 return null == input ? null : Longs.toArray(input); 216 }}; 217 private final Function<List<Double>,double[]> list2doubleArray = new Function<List<Double>,double[]>(){ 218 @Override 219 public double[] apply(List<Double> input) { 220 return null == input ? null : Doubles.toArray(input); 221 }}; 222 private final Function<List<Double>,float[]> list2floatArray = new Function<List<Double>,float[]>(){ 223 @Override 224 public float[] apply(List<Double> input) { 225 return null == input ? null : Floats.toArray(input); 226 }}; 227 private final Function<List<Short>,short[]> list2shortArray = new Function<List<Short>,short[]>(){ 228 @Override 229 public short[] apply(List<Short> input) { 230 return null == input ? null : Shorts.toArray(input); 231 }}; 232 private final Function<List<Boolean>,boolean[]> list2booleanArray = new Function<List<Boolean>,boolean[]>(){ 233 @Override 234 public boolean[] apply(List<Boolean> input) { 235 return null == input ? null : Booleans.toArray(input); 236 }}; 237 protected final Table<Class<?>,Class<?>,Function<?,?>> transTable = HashBasedTable.create(); 238 public BaseTypeTransformer() { 239 transTable.put(byte[].class,ByteBuffer.class,byteArray2ByteBufferFun); 240 transTable.put(ByteBuffer.class,byte[].class,byteBuffer2ByteArrayFun); 241 transTable.put(Float.class,Double.class,float2DoubleFun); 242 transTable.put(Double.class,Float.class,double2FloatFun); 243 transTable.put(float.class,double.class,float2DoubleFun); 244 transTable.put(float.class,Double.class,float2DoubleFun); 245 transTable.put(double.class,float.class,double2FloatFun); 246 transTable.put(double.class,Float.class,double2FloatFun); 247 transTable.put(Date.class, Long.class, date2LongFunction); 248 transTable.put(java.sql.Date.class, Long.class, date2LongFunction); 249 transTable.put(java.sql.Time.class,Long.class,date2LongFunction); 250 transTable.put(Long.class,Date.class,long2DateFun); 251 transTable.put(Long.class,java.sql.Date.class,long2SqlDateFun); 252 transTable.put(Long.class,java.sql.Time.class,long2SqlTimeFun); 253 transTable.put(URL.class,String.class,url2StringFun); 254 transTable.put(URI.class,String.class,uri2StringFun); 255 transTable.put(String.class,URL.class,string2UrlFun); 256 transTable.put(String.class,URI.class,string2UriFun); 257 transTable.put(int[].class,List.class,intArray2List); 258 transTable.put(long[].class,List.class,longArray2List); 259 transTable.put(double[].class,List.class,doubleArray2List); 260 transTable.put(float[].class,List.class,floatArray2List); 261 transTable.put(short[].class,List.class,shortArray2List); 262 transTable.put(boolean[].class,List.class,booleanArray2List); 263 transTable.put(List.class,int[].class,list2intArray); 264 transTable.put(List.class,long[].class,list2longArray); 265 transTable.put(List.class,double[].class,list2doubleArray); 266 transTable.put(List.class,float[].class,list2floatArray); 267 transTable.put(List.class,short[].class,list2shortArray); 268 transTable.put(List.class,boolean[].class,list2booleanArray); 269 transTable.put(Boolean.class, boolean.class, booleanTypeFun); 270 transTable.put(Character.class, Character.class, charTypeFun); 271 transTable.put(Byte.class, byte.class, byteTypeFun); 272 transTable.put(Short.class, short.class, shortTypeFun); 273 transTable.put(Integer.class, int.class, intTypeFun); 274 transTable.put(Long.class, long.class, longTypeFun); 275 transTable.put(Float.class, float.class, floatTypeFun); 276 transTable.put(Double.class, double.class, doubleTypeFun); 277 transTable.put(Void.class, void.class, voidTypeFun); 278 } 279 /** 280 * 设置{@code left -> right}的转æ¢å™¨ï¼Œå‚æ•°ä¸å¯ä¸º{@code null} 281 * @param left 282 * @param right 283 * @param trans 转æ¢å™¨å¯¹è±¡ 284 * @return 285 */ 286 public <L,R>BaseTypeTransformer setTransformer(Class<L> left, Class<R> right, Function<L, R> trans){ 287 checkArgument(null != left && null != right && null != trans,"left, right, trans must not be null"); 288 synchronized (this.transTable) { 289 transTable.put(left,right,trans); 290 return this; 291 } 292 } 293 /** 294 * 返回{@code left TO right}指定的转æ¢å™¨ï¼Œå‚æ•°ä¸å¯ä¸º{@code null} 295 * @param left 296 * @param right 297 * @return 298 */ 299 @SuppressWarnings({ "unchecked", "rawtypes" }) 300 public <L,R>Function<L,R> getTransformer(Class<L>left,Class<R>right){ 301 checkArgument(null != left && null != right,"left, right must not be null"); 302 if(right.isAssignableFrom(left)){ 303 // 相åŒç±»åž‹è½¬æ¢ 304 return (Function<L,R>)this.sameTypeFun; 305 } 306 Function<L, R> result = (Function<L, R>) this.transTable.get(left, right); 307 if (null == result) { 308 if (Enum.class.isAssignableFrom(left) && Enum.class.isAssignableFrom(left)) { 309 // æ·»åŠ æžšä¸¾ç±»åž‹è½¬æ¢ 310 synchronized (this.transTable) { 311 // double checking 312 if (null == (result = (Function<L, R>) this.transTable.get(left, right))) { 313 result = new EnumTransformer((Class<? extends Enum<?>>) left, 314 (Class<? extends Enum<?>>) right); 315 setTransformer(left, right, (Function<L,R>)result); 316 } 317 } 318 } 319 } 320 return result; 321 } 322 public <L,R>Function<L,R> getTransformerChecked(Class<L>left,Class<R>right){ 323 return checkNotNull(getTransformer(left,right),"not found transformer for %s to %s",left,right); 324 } 325 326 /** 327 * å°†{@code value}转æ¢ä¸º{@code right}指定的类型 328 * @param value 329 * @param left {@code value}的原类型 330 * @param right ç›®æ ‡ç±»åž‹ 331 * @return 332 */ 333 @SuppressWarnings("unchecked") 334 public <L,R> R to (L value,Class<L>left,Class<R> right){ 335 if(null == value){ 336 return null; 337 } 338 checkArgument(null != right,"right is null"); 339 if(right.isInstance(value)){ 340 return (R) value; 341 } 342 return this.getTransformerChecked(left, right).apply(value); 343 } 344 /** 345 * å°† List ä¸çš„å…ƒç´ è½¬æ¢ä¸º{@code right}指定的类型 346 * @param input 347 * @param left åˆ—è¡¨å…ƒç´ åŽŸç±»åž‹ 348 * @param right åˆ—è¡¨å…ƒç´ ç›®æ ‡ç±»åž‹ 349 * @return 350 */ 351 public <L,R>List<R> to(List<L> input,Class<L> left, Class<R> right){ 352 return null == input 353 ? null 354 : Lists.transform(input, this.getTransformerChecked(left, right)); 355 } 356 /** 357 * å°† Set ä¸çš„å…ƒç´ è½¬æ¢ä¸º{@code right}指定的类型 358 * @param input 359 * @param left 集åˆå…ƒç´ 原类型 360 * @param right 集åˆå…ƒç´ ç›®æ ‡ç±»åž‹ 361 * @return 362 */ 363 public <L,R> Set<R> to(Set<L> input,Class<L> left, Class<R> right){ 364 return null == input 365 ? null 366 : Sets.newHashSet(Iterables.transform(input, this.getTransformerChecked(left, right))); 367 } 368 /** 369 * å°† 数组 ä¸çš„å…ƒç´ è½¬æ¢ä¸º{@code right}指定的类型 370 * @param input 371 * @param left æ•°ç»„å…ƒç´ åŽŸç±»åž‹ 372 * @param right æ•°ç»„å…ƒç´ ç›®æ ‡ç±»åž‹ 373 * @return 374 */ 375 public <L,R> List<R> to(L[] input,Class<L> left,Class<R> right){ 376 if(null == input){ 377 return null; 378 } 379 return to(Arrays.asList(input),left,right); 380 } 381 /** 382 * å°† int[] 转æ¢ä¸ºåˆ—表 383 * @param input 384 * @param left 385 * @param right 386 * @return 387 */ 388 public List<Integer> to(int[] input,Class<Integer>left,Class<Integer> right){ 389 return intArray2List.apply(input); 390 } 391 /** 392 * å°† long[] 转æ¢ä¸ºåˆ—表 393 * @param input 394 * @param left 395 * @param right 396 * @return 397 */ 398 public List<Long> to(long[] input,Class<Long>left,Class<Long> right){ 399 return longArray2List.apply(input); 400 } 401 /** 402 * å°† double[] 转æ¢ä¸ºåˆ—表 403 * @param input 404 * @param left 405 * @param right 406 * @return 407 */ 408 public List<Double> to(double[] input,Class<Double>left,Class<Double> right){ 409 return doubleArray2List.apply(input); 410 } 411 /** 412 * å°† float[] 转æ¢ä¸ºDouble列表 413 * @param input 414 * @param left 415 * @param right 416 * @return 417 */ 418 public List<Double> to(float[] input,Class<Float>left,Class<Double> right){ 419 return floatArray2List.apply(input); 420 } 421 /** 422 * å°† short[] 转æ¢ä¸ºåˆ—表 423 * @param input 424 * @param left 425 * @param right 426 * @return 427 */ 428 public List<Short> to(short[] input,Class<Short>left,Class<Short> right){ 429 return shortArray2List.apply(input); 430 } 431 /** 432 * å°† boolean[] 转æ¢ä¸ºåˆ—表 433 * @param input 434 * @param left 435 * @param right 436 * @return 437 */ 438 public List<Boolean> to(boolean[] input,Class<Boolean>left,Class<Boolean> right){ 439 return booleanArray2List.apply(input); 440 } 441 /** 442 * å°† 列表 转æ¢ä¸ºæ•°ç»„ 443 * @param input 444 * @param left åˆ—è¡¨å…ƒç´ ç±»åž‹ 445 * @param right æ•°ç»„å…ƒç´ ç±»åž‹ 446 * @return 447 */ 448 @SuppressWarnings("unchecked") 449 public <L,R> R[] toArray(List<L> input,Class<L> left,Class<R> right){ 450 if(null == input){ 451 return null; 452 } 453 List<R> r = to(input,left,right); 454 return r.toArray((R[]) Array.newInstance(right, r.size())); 455 } 456 /** 457 * å°† Integer 列表 转æ¢ä¸ºæ•°ç»„ 458 * @param input 459 * @param left 460 * @param right 461 * @return 462 */ 463 public int[] tointArray(List<Integer> input,Class<Integer> left,Class<Integer> right){ 464 return list2intArray.apply(input); 465 } 466 /** 467 * å°† Long 列表 转æ¢ä¸ºæ•°ç»„ 468 * @param input 469 * @param left 470 * @param right 471 * @return 472 */ 473 public long[] tolongArray(List<Long> input,Class<Long> left,Class<Long> right){ 474 return list2longArray.apply(input); 475 } 476 /** 477 * å°† Double 列表 转æ¢ä¸ºæ•°ç»„ 478 * @param input 479 * @param left 480 * @param right 481 * @return 482 */ 483 public double[] todoubleArray(List<Double>input,Class<Double> left,Class<Double> right){ 484 return list2doubleArray.apply(input); 485 } 486 /** 487 * å°† Double 列表 转æ¢ä¸ºfloat数组 488 * @param input 489 * @param left 490 * @param right 491 * @return 492 */ 493 public float[] tofloatArray(List<Double>input,Class<Double> left,Class<Float> right){ 494 return list2floatArray.apply(input); 495 } 496 /** 497 * å°† Short 列表 转æ¢ä¸ºæ•°ç»„ 498 * @param input 499 * @param left 500 * @param right 501 * @return 502 */ 503 public short[] toshortArray(List<Short>input,Class<Short> left,Class<Short> right){ 504 return list2shortArray.apply(input); 505 } 506 /** 507 * å°† Boolean 列表 转æ¢ä¸ºæ•°ç»„ 508 * @param input 509 * @param left 510 * @param right 511 * @return 512 */ 513 public boolean[] tobooleanArray(List<Boolean>input,Class<Boolean> left,Class<Boolean> right){ 514 return list2booleanArray.apply(input); 515 } 516 /** 517 * å°†{@code Map<K1,V1>}转æ¢ä¸º{@code Map<K2,V2>} 518 * @param input 519 * @param k1 520 * @param v1 521 * @param k2 522 * @param v2 523 * @return 524 */ 525 @SuppressWarnings("unchecked") 526 public <K1,V1,K2,V2> Map<K2,V2> to(Map<K1,V1>input,Class<K1>k1,Class<V1>v1,Class<K2> k2,Class<V2> v2){ 527 checkArgument(null != k1 && null != v1 && null != k2 && null != v2,"k1,v1,k2,v2 must not be null"); 528 if(k1 == k2){ 529 if(v1 == v2){ 530 return (Map<K2, V2>) input; 531 } 532 return (Map<K2, V2>) Maps.transformValues(input, this.getTransformerChecked(v1, v2)); 533 }else{ 534 Map<K2, V1> k2v1 = transform(input,this.getTransformerChecked(k1, k2)); 535 if(v1 == v2){ 536 return (Map<K2, V2>) k2v1; 537 }else{ 538 return Maps.transformValues(k2v1, this.getTransformerChecked(v1, v2)); 539 } 540 } 541 } 542 /** 543 * å°†{@code value}转æ¢ä¸º{@code right}指定的类型 544 * @param value 545 * @param left {@code value}的原类型 546 * @param right ç›®æ ‡ç±»åž‹ 547 * @return 548 */ 549 @SuppressWarnings({ "unchecked", "rawtypes" }) 550 public <L, R> R cast(Object value, Type left, Type right) { 551 TypeToken<?> leftToken = TypeToken.of(checkNotNull(left)); 552 TypeToken<?> rightToken = TypeToken.of(checkNotNull(right)); 553 if(null == value){ 554 // right为primitive类型时 valueä¸å¯ä¸ºnull,å¦åˆ™æŠ›å‡ºå¼‚常 555 checkArgument(! ((right instanceof Class<?>) && ((Class<?>)right).isPrimitive()),"cant cast null to primitive type %s",right); 556 return null; 557 } 558 // object to object 559 if( left instanceof Class<?> && right instanceof Class<?>){ 560 return to((L)value,(Class<L>)left, (Class<R>)right); 561 } 562 // list to array 563 if(List.class.isAssignableFrom(leftToken.getRawType()) && null != rightToken.getComponentType()){ 564 Class<?> componentType = rightToken.getComponentType().getRawType(); 565 if(componentType == int.class){ 566 return (R) tointArray((List<Integer>)value, Integer.class, int.class); 567 } 568 if(componentType == long.class){ 569 return (R) tolongArray((List<Long>)value, Long.class, long.class); 570 } 571 if(componentType == double.class){ 572 return (R) todoubleArray((List<Double>)value, Double.class, double.class); 573 } 574 if(componentType == float.class){ 575 return (R) tofloatArray((List<Double>)value, Double.class, float.class); 576 } 577 if(componentType == short.class){ 578 return (R) toshortArray((List<Short>)value, Short.class, short.class); 579 } 580 if(componentType == boolean.class){ 581 return (R) tobooleanArray((List<Boolean>)value, Boolean.class, boolean.class); 582 } 583 Type elementType = ((ParameterizedType)left).getActualTypeArguments()[0]; 584 if(elementType instanceof Class<?>){ 585 return (R) toArray((List<L>)value,(Class<L>)elementType,(Class<R>)componentType); 586 } 587 throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right)); 588 } 589 // list to list 590 if(List.class.isAssignableFrom(leftToken.getRawType()) && List.class == rightToken.getRawType()){ 591 checkArgument(value instanceof List); 592 Type leftElementType = ((ParameterizedType)left).getActualTypeArguments()[0]; 593 Type rightElementType = ((ParameterizedType)right).getActualTypeArguments()[0]; 594 if(leftElementType instanceof Class<?>&& rightElementType instanceof Class<?>){ 595 return (R) to((List<L>)value,(Class<L>)leftElementType,(Class<R>)rightElementType); 596 } 597 throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right)); 598 } 599 // set to set 600 if(Set.class.isAssignableFrom(leftToken.getRawType()) && Set.class == rightToken.getRawType()){ 601 checkArgument(value instanceof Set); 602 Type leftElementType = ((ParameterizedType)left).getActualTypeArguments()[0]; 603 Type rightElementType = ((ParameterizedType)right).getActualTypeArguments()[0]; 604 if(leftElementType instanceof Class<?>&& rightElementType instanceof Class<?>){ 605 return (R) to((Set<L>)value,(Class<L>)leftElementType,(Class<R>)rightElementType); 606 } 607 throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right)); 608 } 609 // map to map 610 if(Map.class.isAssignableFrom(leftToken.getRawType()) && Map.class == rightToken.getRawType()){ 611 Type k1Type = ((ParameterizedType)left).getActualTypeArguments()[0]; 612 Type v1Type = ((ParameterizedType)left).getActualTypeArguments()[1]; 613 Type k2Type = ((ParameterizedType)right).getActualTypeArguments()[0]; 614 Type v2Type = ((ParameterizedType)right).getActualTypeArguments()[1]; 615 if(k1Type instanceof Class<?> 616 && v1Type instanceof Class<?> 617 && k2Type instanceof Class<?> 618 && v2Type instanceof Class<?>){ 619 to((Map)value,(Class<?>)k1Type,(Class<?>)v1Type,(Class<?>)k2Type,(Class<?>)v2Type); 620 } 621 throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right)); 622 } 623 // array to list 624 if(leftToken.isArray() && List.class == rightToken.getRawType()){ 625 checkArgument(value.getClass().isArray()); 626 Type componentType = leftToken.getComponentType().getType(); 627 if(componentType == int.class){ 628 return (R) to((int[])value, int.class, Integer.class); 629 } 630 if(componentType == long.class){ 631 return (R) to((long[])value, long.class, Long.class); 632 } 633 if(componentType == double.class){ 634 return (R) to((double[])value, double.class, Double.class); 635 } 636 if(componentType == float.class){ 637 return (R) to((float[])value, float.class, Double.class); 638 } 639 if(componentType == short.class){ 640 return (R) to((short[])value, short.class, Short.class); 641 } 642 if(componentType == boolean.class){ 643 return (R) to((boolean[])value, boolean.class, Boolean.class); 644 } 645 Type rightElementType = ((ParameterizedType)right).getActualTypeArguments()[0]; 646 if((leftToken.getComponentType().getType()) instanceof Class<?> 647 && rightElementType instanceof Class<?>){ 648 return (R) to((L[])value,(Class<L>)componentType,(Class<R>)rightElementType); 649 } 650 throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right)); 651 } 652 throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right)); 653 } 654 /** 655 * convert {@code Map<K1,V>} to {@code Map<K2,V>} 656 * @return {@linkplain ImmutableMap} 657 */ 658 private static final <K1,K2,V>Map<K2,V> transform(Map<K1,V>fromMap,final Function<K1,K2>transformer){ 659 checkNotNull(fromMap,"fromMap is null"); 660 checkNotNull(transformer,"transformer is null"); 661 // æ–°çš„Map对象Keyç±»åž‹å·²ç»æ˜¯K2äº†ï¼Œåªæ˜¯Value类型æˆäº†Entry 662 ImmutableMap<K2, Entry<K1, V>> k2Entry = Maps.uniqueIndex(fromMap.entrySet(), new Function<Entry<K1, V>,K2>(){ 663 @Override 664 public K2 apply(Entry<K1, V> input) { 665 return transformer.apply(input.getKey()); 666 }}); 667 // å†åšä¸€æ¬¡è½¬æ¢å°†Entry<K1, V>è½¬æ¢æˆV,这个过程并没有创建新的Map,åªæ˜¯åˆ›å»ºäº†k2Entry的代ç†å¯¹è±¡ 668 Map<K2, V> k2V = Maps.transformEntries(k2Entry, new EntryTransformer<K2,Entry<K1,V>,V>(){ 669 @Override 670 public V transformEntry(K2 key, Entry<K1, V> value) { 671 return value.getValue(); 672 }}); 673 return k2V; 674 } 675}