Как получить подмножество значений для определенного ключа в HashMap‹String, Object› initialMap = new HashMap‹String, Object›()

у меня есть

HashMap<String, Object> initialMap = new HashMap<String, Object>();

в котором у меня есть набор строковых значений для ключа таким образом,

error=[e1, e2, e3, e4, e5, e6],[e7, e8, e9, e10, e11, e12],[e13, e14 ,e15, e16, e17, e18],[e19, e20, e21, e22, e23, e24],[e25, e26, e27, e28, e29, e30], status=[s1, s2, s3, s4, s5, s6],[s7, s8 s9, s10, s11, s12],[s13, s14 ,s15, s16, s17, s18],[s19, s20, s21, s22, s23, s24],[s25, s26, s27, s28, s29, s30], data=[[d1, d2, d3, d4, d5, d6],[d7, d8, d9, d10, d11, d12],[d13, d14 ,d15, d16, d17, d18],[d19, d20, d21, d22, d23, d24],[d25, d26, d27, d28, d29, d30]], warning=[w1, w2, w3, w4, w5, w6],[w7, w8, w9, w10, w11, w12],[w13, w14 ,w15, w16, w17, w18],[w19, w20, w21, w22, w23, w24],[w25, w26, w27, w28, w29, w30]}

Итак, здесь для ключа с именем ошибка,

у нас есть эти 5 наборов строковых значений ниже.

[e1, e2, e3, e4, e5, e6],[e7, e8, e9, e10, e11, e12],[e13, e14 ,e15, e16, e17, e18],[e19, e20, e21, e22, e23, e24],[e25, e26, e27, e28, e29, e30].

Мне не нужны все эти 5 заданных значений для ключа, но мне нужно использовать начальный и конечный предел, т.е. подмножество значений для каждого ключа.

Скажем, если мой startLimit=2 и endLimit=4, тогда я должен получить только набор значений 2,3,4 для ошибки ключа,

[e7, e8, e9, e10, e11, e12],[e13, e14 ,e15, e16, e17, e18],[e19, e20, e21, e22, e23, e24]

также нужно повторить для всех остальных 3 ключей.

Я пробовал этот способ, но он всегда дает мне все значения определенного ключа.

Есть ли способ получить подмножество значений для определенного ключа в хэш-карте?

Вот код, который я пробовал,

public class MapTest {
        HashMap<String, Object> finalMap = new HashMap<String, Object>();
        int startLimit = 2;
        int endLimit = 4;

        public static void main(String[] args) {
            MapTest mm = new MapTest();
            mm.getData();
        }
        public void getData()
        {
            HashMap<String, Object> initialMap = new HashMap<String, Object>();
            initialMap.put("status","[s1, s2, s3, s4, s5, s6],[s7, s8 s9, s10, s11, s12],[s13, s14 ,s15, s16, s17, s18],[s19, s20, s21, s22, s23, s24],[s25, s26, s27, s28, s29, s30]");
            initialMap.put("data","[[d1, d2, d3, d4, d5, d6],[d7, d8, d9, d10, d11, d12],[d13, d14 ,d15, d16, d17, d18],[d19, d20, d21, d22, d23, d24],[d25, d26, d27, d28, d29, d30]]");
            initialMap.put("warning","[w1, w2, w3, w4, w5, w6],[w7, w8, w9, w10, w11, w12],[w13, w14 ,w15, w16, w17, w18],[w19, w20, w21, w22, w23, w24],[w25, w26, w27, w28, w29, w30]");
            initialMap.put("error","[e1, e2, e3, e4, e5, e6],[e7, e8, e9, e10, e11, e12],[e13, e14 ,e15, e16, e17, e18],[e19, e20, e21, e22, e23, e24],[e25, e26, e27, e28, e29, e30]");

            Set<Entry<String, Object>> entries = initialMap .entrySet();
            for (Iterator<Entry<String, Object>> i = entries.iterator(); i.hasNext(); ) {
                Entry e = (Entry) i.next();
                if(e.getKey().equals("error"))
                {   
                    Object errValue = initialMap.get(e.getKey());
                    //System.out.println("errValue" + errValue);
                    finalMap.put(e.getKey().toString(), errValue);
                }
                if(e.getKey().equals("data"))
                {   
                    Object errValue = initialMap.get(e.getKey());
                    //System.out.println("errValue" + errValue);
                    finalMap.put(e.getKey().toString(), errValue);
                }
                else if(e.getKey().equals("warning"))
                {   
                    Object errValue = initialMap.get(e.getKey());
                    //System.out.println("errValue" + errValue);
                    finalMap.put(e.getKey().toString(), errValue);
                }
                if(e.getKey().equals("status"))
                {   
                    Object errValue = initialMap.get(e.getKey());
                    //System.out.println("errValue" + errValue);
                    finalMap.put(e.getKey().toString(), errValue);
                }
            }
            if(startLimit == 2 && endLimit == 4)
                System.out.println("final map after limiting the data " + finalMap);
        } 
    }

Я получаю все 5 пар значений для ключа таким образом из приведенной выше программы,

финальная карта после ограничения данных

{error=[e1, e2, e3, e4, e5, e6],[e7, e8, e9, e10, e11, e12],[e13, e14 ,e15, e16, e17, e18],[e19, e20, e21, e22, e23, e24],[e25, e26, e27, e28, e29, e30], status=[s1, s2, s3, s4, s5, s6],[s7, s8 s9, s10, s11, s12],[s13, s14 ,s15, s16, s17, s18],[s19, s20, s21, s22, s23, s24],[s25, s26, s27, s28, s29, s30], data=[[d1, d2, d3, d4, d5, d6],[d7, d8, d9, d10, d11, d12],[d13, d14 ,d15, d16, d17, d18],[d19, d20, d21, d22, d23, d24],[d25, d26, d27, d28, d29, d30]], warning=[w1, w2, w3, w4, w5, w6],[w7, w8, w9, w10, w11, w12],[w13, w14 ,w15, w16, w17, w18],[w19, w20, w21, w22, w23, w24],[w25, w26, w27, w28, w29, w30]}

НО мне нужно пройти этот путь, так как мой лимит составляет от 2 до 4 пар,

финальная карта после ограничения данных {error=[e7, e8, e9, e10, e11, e12],[e13, e14 ,e15, e16, e17, e18],[e19, e20, e21, e22, e23, e24], status=[s7, s8 s9, s10, s11, s12],[s13, s14 ,s15, s16, s17, s18],[s19, s20, s21, s22, s23, s24], data=[[d7, d8, d9, d10, d11, d12],[d13, d14 ,d15, d16, d17, d18],[d19, d20, d21, d22, d23, d24]], warning=[w7, w8, w9, w10, w11, w12],[w13, w14 ,w15, w16, w17, w18],[w19, w20, w21, w22, w23, w24]}

Может ли кто-нибудь помочь мне в этом вопросе?

Спасибо


person Sandy    schedule 18.03.2016    source источник


Ответы (2)


Я вижу 2 большие проблемы в вашем коде:

  1. startLimit и endLimit не используются для фильтрации данных, извлеченных из initialMap, а просто проверяются на значении i; ваш код просто скопирует ключ/значение из initialMap в finalMap, а затем напечатает finalMap, если два ограничения установлены на 2 и 4 (они просто помечаются, чтобы решить, печатать или нет
  2. каждая клавиша в initialMap связана с String (а не с Object или List), поэтому единственный способ, которым я вижу разделение «объектов квадратных скобок», - это игра с запятыми ... но я не уверен, что это цель вашего кода

Я предлагаю вам изменить значения карты на List<String> и переосмыслить логику getData.

public static void main(String[] args) {
    int startLimit = 2;
    int endLimit = 4;

    HashMap<String, List<String>> finalMap = new HashMap<>();
    HashMap<String, List<String>> initialMap = new HashMap<>();

    List<String> sList = Arrays.asList("[s1, s2, s3, s4, s5, s6]", "[s7, s8, s9, s10, s11, s12]", "[s13, s14 ,s15, s16, s17, s18]", "[s19, s20, s21, s22, s23, s24]", "[s25, s26, s27, s28, s29, s30]");
    List<String> dList = Arrays.asList("[d1, d2, d3, d4, d5, d6]", "[d7, d8, d9, d10, d11, d12]", "[d13, d14 ,d15, d16, d17, d18]", "[d19, d20, d21, d22, d23, d24]", "[d25, d26, d27, d28, d29, d30]");
    List<String> wList = Arrays.asList("[w1, w2, w3, w4, w5, w6]", "[w7, w8, w9, w10, w11, w12]", "[w13, w14 ,w15, w16, w17, w18]", "[w19, w20, w21, w22, w23, w24]", "[w25, w26, w27, w28, w29, w30]");
    List<String> eList = Arrays.asList("[e1, e2, e3, e4, e5, e6]", "[e7, e8, e9, e10, e11, e12]", "[e13, e14 ,e15, e16, e17, e18]", "[e19, e20, e21, e22, e23, e24]", "[e25, e26, e27, e28, e29, e30]");

    initialMap.put("status", sList);
    initialMap.put("data", dList);
    initialMap.put("warning", wList);
    initialMap.put("error", eList);

    Iterator<Entry<String, List<String>>> i = initialMap.entrySet().iterator();
    Entry<String, List<String>> e = null;
    List<String> eValue = null;
    while (i.hasNext()) {
        e = i.next();
        eValue = e.getValue();
        finalMap.put(e.getKey(), eValue.subList(startLimit, endLimit));
    }
    System.out.println("final map after limiting the data " + finalMap);
} 

EDIT: если значения карты не могут быть List<String>, вы можете сделать следующее

public static void main(String[] args) {
    int startLimit = 2;
    int endLimit = 4;
    String objectSeparator = "],";

    HashMap<String, String> finalMap = new HashMap<>();
    HashMap<String, String> initialMap = new HashMap<>();

    String sList = "[s1, s2, s3, s4, s5, s6],[s7, s8 s9, s10, s11, s12],[s13, s14 ,s15, s16, s17, s18],[s19, s20, s21, s22, s23, s24],[s25, s26, s27, s28, s29, s30]";
    String dList = "[[d1, d2, d3, d4, d5, d6],[d7, d8, d9, d10, d11, d12],[d13, d14 ,d15, d16, d17, d18],[d19, d20, d21, d22, d23, d24],[d25, d26, d27, d28, d29, d30]]";
    String wList = "[w1, w2, w3, w4, w5, w6],[w7, w8, w9, w10, w11, w12],[w13, w14 ,w15, w16, w17, w18],[w19, w20, w21, w22, w23, w24],[w25, w26, w27, w28, w29, w30]";
    String eList = "[e1, e2, e3, e4, e5, e6],[e7, e8, e9, e10, e11, e12],[e13, e14 ,e15, e16, e17, e18],[e19, e20, e21, e22, e23, e24],[e25, e26, e27, e28, e29, e30]";

    initialMap.put("status", sList);
    initialMap.put("data", dList);
    initialMap.put("warning", wList);
    initialMap.put("error", eList);

    Iterator<Entry<String, String>> it = initialMap.entrySet().iterator();
    Entry<String, String> e = null;
    String eValue = null;
    String[] splitted = null;
    while (it.hasNext()) {
        e = it.next();
        eValue = e.getValue();

        // Split each "square bracket object" in a separate string 
        splitted = eValue.split(objectSeparator);

        // Create a new string containing only objects with index between limits
        String limited = "";
        for(int idx = startLimit-1; idx <= endLimit-1; idx++)
            limited += (splitted[idx] + objectSeparator);

        // Remove trailing comma added inside for loop
        limited = limited.substring(0, limited.lastIndexOf(","));

        finalMap.put(e.getKey(), limited);
    }
    System.out.println("final map after limiting the data " + finalMap);
} 
person Marco Stramezzi    schedule 18.03.2016
comment
если startLimit=2 и endLimit =4, мне нужно 2,3,4, но ваш алгоритм дает только 2,4 - person Sandy; 18.03.2016
comment
Это потому, что subList исключает верхнюю границу. Если это возможно, вы должны настроить свой лимит так, чтобы он находился в диапазоне [0, размер списка]. - person Marco Stramezzi; 18.03.2016
comment
@Macro Stramezzi, мы не можем сделать это с помощью Object .. Я не могу изменить это, чтобы перечислить‹string› - person Sandy; 18.03.2016
comment
@Macro Stramezzi, можем ли мы сделать это, используя сам объект? - person Sandy; 18.03.2016

примечание: я предположил, что значение, связанное с ключом "data", имеет ту же структуру, что и другие значения (без дополнительных квадратных скобок), если это не так, то алгоритм становится немного сложнее.

Я использовал guava и commons-lang3 поверх JDK 6.

HashMap<String, Object> finalMap = Maps.newHashMap(Maps.transformValues(initialMap, new Function<Object, Object>() {
    public Object apply(Object input) {
        String inputAsString = (String) input;
        String trimmedInput = inputAsString.replaceAll("^\\[+", "").replaceAll("\\]+$", "");
        int removedBraces = (inputAsString.length() - trimmedInput.length()) / 2;
        List<String> splitInput = Lists.newArrayList(Splitter.on("],[").split(trimmedInput));
        List<String> subList = splitInput.subList(startLimit - 1, endLimit);
        return StringUtils.repeat('[', removedBraces) + Joiner.on("],[").join(subList)
        + StringUtils.repeat(']', removedBraces);
    }
}));

Короче говоря, этот код создает новую карту, где каждое значение в новой карте строится путем преобразования начального значения с использованием следующего алгоритма:

  1. уберите начальный '[' и завершающий ']'
  2. разделить его на строку "],["
  3. взять подсписок полученного списка (от startLimit - 1 до endLimit)
  4. снова соедините список со строкой, используя «],[», добавив начальный начальный «[» и завершающий «]» назад
person Thomas Naskali    schedule 18.03.2016
comment
как мы можем сделать с 1 дополнительным набором фигурных скобок [] для данных? - person Sandy; 18.03.2016
comment
Вы имеете в виду, есть ли у каждого значения на карте дополнительный набор или только некоторые из них? Если это все значения, то это тривиально (просто удалите 2 символа вместо одного перед разделением и добавьте '[[' и ']]' в конце) - person Thomas Naskali; 18.03.2016
comment
Я обновил свой ответ запрошенным алгоритмом и общими типами. - person Thomas Naskali; 30.03.2016