今天去面试,上机题,第一题就给我难住了求助各位大佬。。。
简单的实现了一个方法
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.lang.reflect.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class TestLength {
private static Map<Class, Method> methods = new ConcurrentHashMap<>();
private static Set<String> methodNames = Sets.newHashSet("length", "size");
public static int length(Object obj) {
int size = 0;
if (obj == null) {
//skip
} else if (obj instanceof String) {
size = ((String) obj).length();
} else if (obj instanceof Collection) {
size = ((Collection) obj).size();
} else if (obj instanceof Map) {
size = ((Map) obj).size();
} else if (obj.getClass().isArray()) {
size = ((Object[]) obj).length;
} else {
//支持自定义size或者length方法(必须是public、非静态、无参、返回类型为int/Integer的才行)
size = findLengthOrSize(obj);
}
return size;
}
private static int findLengthOrSize(Object obj) {
Class clazz = obj.getClass();
//如果没有找到属性,则找length和size的方法
Method method = getLengthOrSizeMethod(clazz);
if (method != null) {
try {
return (Integer) method.invoke(obj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
return obj.toString().length();
}
/**
* 这里可以加一层缓存,同样类型的直接从缓存取,增加性能
*/
public static Method getLengthOrSizeMethod(Class clazz) {
Method method = methods.get(clazz);
if (method == null && !methods.containsKey(clazz)) {
Method[] methodTmp = clazz.getDeclaredMethods();
for (Method m : methodTmp) {
if (methodNames.contains(m.getName()) && checkMethod(m)) {
method = m;
break;
}
}
methods.put(clazz, method);
}
return method;
}
public static boolean checkMethod(Method method) {
int modifier = method.getModifiers();
return method.getParameterCount() == 0
&& Modifier.isPublic(modifier)
&& !Modifier.isStatic(modifier)
&& (method.getReturnType() == int.class
|| method.getReturnType() == Integer.class);
}
public Integer length() {
return 55;
}
public int length(int a, int b) {
return a + b;
}
public static void main(String[] args) {
System.out.println(length("1234"));
System.out.println(length(Lists.newArrayList("asdf", "asd", "asdf")));
System.out.println(length(123123));
Map<String, String> map = new HashMap<>();
map.put("123","22");
System.out.println(length(map));
System.out.println(map.size());
System.out.println(length(map.keySet()));
System.out.println(length(new String[]{"123", "1", "2", "3", "34", "123"}));
System.out.println(length(new TestLength()));
}
}
希望对你有帮助...
有长度类型的就是几类,方法中使用 if 判断其是否为对应类的实例,如果是,则转换为该类型的数据,调用其长度方法返回即可。
参考:
public static int length(Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
if (value == null ) {
return 0;
}
if(value instanceof String) {
return ((String) value).length();
}
if(value instanceof List) {
return ((List) value).size();
}
if(value instanceof Map) {
return ((Map) value).size();
}
if(value instanceof Set) {
return ((Set) value).size();
}
return 0;
}
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
Object c = "111111";
System.out.println("String Object length is:"+length(c));
List c0 = new ArrayList<String>();
c0.add("00");
c0.add("00");
c0.add("00");
c0.add("00");
c0.add("00");
System.out.println("List Object length is:"+length(c0));
Object c1 = new int[2];
System.out.println("Array Object length is:"+length(c1));
HashSet c3 = new HashSet<String>();
c3.add("111");
c3.add("112");
c3.add("113");
System.out.println("Set Object length is:"+length(c3));
Map c4 = new HashMap<String,String>();
c4.put("a1", "ddd");
c4.put("a2", "ddd");
c4.put("a3", "ddd");
c4.put("a4", "ddd");
System.out.println("Map Object length is:"+length(c4));
Object c5 = new Date();
System.out.println("Date Object length is:"+length(c5));
}
最难的点是数组类型的 Object ,因为数组没有 length 属性,所以没有办法获取到数组的长度。