org.apache.hadoop.hive.ql.udf.generic.GenericUDFMapKeys
@Override
public ObjectInspector initialize(ObjectInspector[] arguments)
throws UDFArgumentException {
// 传入的参数为1个
if (arguments.length != 1) {
throw new UDFArgumentLengthException("The function MAP_KEYS only accepts one argument.");
} else if (!(arguments[0] instanceof MapObjectInspector)) {
// 参数类型应该是MAP类型
throw new UDFArgumentTypeException(0, "\""
+ Category.MAP.toString().toLowerCase()
+ "\" is expected at function MAP_KEYS, " + "but \""
+ arguments[0].getTypeName() + "\" is found");
}
// 参数强转为MapObjectInspector
mapOI = (MapObjectInspector) arguments[0];
// 返回一个map的key检查器
ObjectInspector mapKeyOI = mapOI.getMapKeyObjectInspector();
// 返回一个列表
return ObjectInspectorFactory.getStandardListObjectInspector(mapKeyOI);
}
在上面的源码之后,需要知道返回的列表是怎么执行的,点进去ObjectInspectorFactory类看getStandardListObjectInspector方法
public static StandardListObjectInspector getStandardListObjectInspector(ObjectInspector listElementObjectInspector) {
StandardListObjectInspector result = (StandardListObjectInspector)cachedStandardListObjectInspector.get(listElementObjectInspector);
if (result == null) {
result = new StandardListObjectInspector(listElementObjectInspector);
StandardListObjectInspector prev = (StandardListObjectInspector)cachedStandardListObjectInspector.putIfAbsent(listElementObjectInspector, result);
if (prev != null) {
result = prev;
}
}
return result;
}
其中cachedStandardListObjectInspector的声明如下
static ConcurrentHashMap<ObjectInspector, StandardListObjectInspector> cachedStandardListObjectInspector = new ConcurrentHashMap();
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
retArray.clear();
Object mapObj = arguments[0].get();
Map<?,?> mapVal = mapOI.getMap(mapObj);
if (mapVal != null) {
retArray.addAll(mapVal.keySet());
}
return retArray;
}
@Override
public String getDisplayString(String[] children) {
assert children.length == 1;
return getStandardDisplayString("map_keys", children);
}
protected String getStandardDisplayString(String name, String[] children) {
return getStandardDisplayString(name, children, ", ");
}
调用了重载方法,一点点的把数组内的数据append到字符中
protected String getStandardDisplayString(String name, String[] children, String delim) {
StringBuilder sb = new StringBuilder();
sb.append(name);
sb.append("(");
if (children.length > 0) {
sb.append(children[0]);
for (int i = 1; i < children.length; i++) {
sb.append(delim);
sb.append(children[i]);
}
}
sb.append(")");
return sb.toString();
}