001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package net.tridentsdk.util; 019 020import com.google.common.base.Function; 021import com.google.common.reflect.TypeToken; 022 023import javax.annotation.concurrent.ThreadSafe; 024import java.lang.reflect.Array; 025 026/** 027 * Tools for modifying elements of an array 028 * 029 * <p>Expect this to be very slow, uses LOAD of reflection to simplify array tasks at the cost of performance</p> 030 * 031 * @param <T> the type held by the array to be converted 032 */ 033@ThreadSafe 034public final class ArrayTool<T> { 035 private final T[] array; 036 private final TypeToken<T> typeToken = new TypeToken<T>() { 037 }; 038 039 private ArrayTool(T[] array) { 040 this.array = array; 041 } 042 043 /** 044 * Creates a new array tool 045 * 046 * @param array the underlying array 047 * @param <T> the type of the array 048 * @return the new array tool 049 */ 050 public static <T> ArrayTool<T> using(T[] array) { 051 return new ArrayTool<>(array); 052 } 053 054 /** 055 * Converts the underlying array to an array of the type specified 056 * 057 * @param c the classtype for the new array 058 * @param <C> the array type 059 * @return the new array converted from the underlying array 060 * @throws java.lang.ClassCastException if the type of the underlying array cannot be cast to the new type 061 */ 062 public <C> C[] convertTo(Class<C> c) { 063 C[] cs = (C[]) Array.newInstance(c, array.length); 064 for (int i = 0; i < array.length; i++) { 065 cs[i] = (C) array[i]; 066 } 067 068 return cs; 069 } 070 071 /** 072 * Creates a deep copy of an array, assuming that its {@link Object#clone()} method returns a deep copy 073 * 074 * @return the deep copy of the underlying array 075 */ 076 public T[] cloneArray(Function<T, T> cloner) { 077 T[] ts = (T[]) Array.newInstance(typeToken.getRawType(), array.length); 078 for (int i = 0; i < array.length; i++) { 079 ts[i] = cloner.apply(array[i]); 080 } 081 082 return ts; 083 } 084 085 /** 086 * Gets the array of this tool 087 * 088 * @return the array passed in during instantiation 089 */ 090 public T[] underlyingArray() { 091 return this.array; 092 } 093}