Java tutorial
//package com.java2s; /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Array; import java.util.List; import java.util.Map; public class Main { /** * Searches a map for a given key. The key can be a regular map key, or a * simple expression of the form: * * <ul> * <li>foo.bar (will lookup 'foo', and then 'bar' in a potential nested map) * </li> * <li>foo.bar[0].baz (will lookup 'foo', then 'bar' in a potential nested * map, then pick the first element in case it is a list/array and then pick * 'baz' from the potential map at that position). * </ul> * * @param map * the map to search in * @param key * the key to resolve * @return the object in the map with the given key/expression. Or null if * it does not exist. */ public static Object find(Map<?, ?> map, String key) { if (map == null || key == null) { return null; } final Object result = map.get(key); if (result == null) { return find(map, key, 0); } return result; } private static Object find(Map<?, ?> map, String key, int fromIndex) { final int indexOfDot = key.indexOf('.', fromIndex); final int indexOfBracket = key.indexOf('[', fromIndex); int indexOfEndBracket = -1; int arrayIndex = -1; boolean hasDot = indexOfDot != -1; boolean hasBracket = indexOfBracket != -1; if (hasBracket) { // also check that there is an end-bracket indexOfEndBracket = key.indexOf("]", indexOfBracket); hasBracket = indexOfEndBracket != -1; if (hasBracket) { final String indexString = key.substring(indexOfBracket + 1, indexOfEndBracket); try { arrayIndex = Integer.parseInt(indexString); } catch (NumberFormatException e) { // not a valid array/list index hasBracket = false; } } } if (hasDot && hasBracket) { if (indexOfDot > indexOfBracket) { hasDot = false; } else { hasBracket = false; } } if (hasDot) { final String prefix = key.substring(0, indexOfDot); final Object nestedObject = map.get(prefix); if (nestedObject == null) { return find(map, key, indexOfDot + 1); } if (nestedObject instanceof Map) { final String remainingPart = key.substring(indexOfDot + 1); @SuppressWarnings("unchecked") final Map<String, ?> nestedMap = (Map<String, ?>) nestedObject; return find(nestedMap, remainingPart); } } if (hasBracket) { final String prefix = key.substring(0, indexOfBracket); final Object nestedObject = map.get(prefix); if (nestedObject == null) { return find(map, key, indexOfBracket + 1); } String remainingPart = key.substring(indexOfEndBracket + 1); try { final Object valueAtIndex; if (nestedObject instanceof List) { valueAtIndex = ((List<?>) nestedObject).get(arrayIndex); } else if (nestedObject.getClass().isArray()) { valueAtIndex = Array.get(nestedObject, arrayIndex); } else { // no way to extract from a non-array and non-list valueAtIndex = null; } if (valueAtIndex != null) { if (remainingPart.startsWith(".")) { remainingPart = remainingPart.substring(1); } if (remainingPart.isEmpty()) { return valueAtIndex; } if (valueAtIndex instanceof Map) { @SuppressWarnings("unchecked") final Map<String, ?> nestedMap = (Map<String, ?>) valueAtIndex; return find(nestedMap, remainingPart); } else { // not traversing any further. Should we want to add // support for double-sided arrays, we could do it here. } } } catch (IndexOutOfBoundsException e) { return null; } } return null; } }