Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于键将映射中的值中的值相互合并_Java_Arrays_Merge_Hashmap_Maps - Fatal编程技术网

Java 基于键将映射中的值中的值相互合并

Java 基于键将映射中的值中的值相互合并,java,arrays,merge,hashmap,maps,Java,Arrays,Merge,Hashmap,Maps,我被这个奇怪的问题困扰了两个小时(我是哑巴) 我有一个带有 A=1,2,3 B=4,5 C=6 我正在寻找的输出是 A=1&B=4&C=6 A=1&B=5&C=6 A=2&B=4&C=6 A=2&B=5&C=6 A=3&B=4&C=6 A=3&B=5&C=6 到目前为止我所做的:- 基于第一个键在映射上迭代,并将值存储在数组中 迭代第二个键,但我不确定如何将第一个结果中的值合并到此结果中 忘记第三个键和后续键 这听起来可能是一个非常愚蠢的问题,但我无法理解。我试图避免这种情况,但我无

我被这个奇怪的问题困扰了两个小时(我是哑巴)

我有一个带有

  • A=1,2,3
  • B=4,5
  • C=6
我正在寻找的输出是

  • A=1&B=4&C=6
  • A=1&B=5&C=6
  • A=2&B=4&C=6
  • A=2&B=5&C=6
  • A=3&B=4&C=6
  • A=3&B=5&C=6
到目前为止我所做的:-

  • 基于第一个键在映射上迭代,并将值存储在数组中
  • 迭代第二个键,但我不确定如何将第一个结果中的值合并到此结果中
  • 忘记第三个键和后续键
这听起来可能是一个非常愚蠢的问题,但我无法理解。我试图避免这种情况,但我无法改变

请帮忙


注意:-我也使用了multiset,但它接受重复的值作为值,因此必须使用一个集合。因此,最终得到了一个
map

以下代码可以处理地图的任何大小(空除外),以及每个集合的任何大小(空除外)。空映射/集将引发错误

当然,一旦定义了预期的输出,扩展代码以处理empty应该相当简单

Map<String, Set<String>> map = new LinkedHashMap<>();
map.put("A", new LinkedHashSet<>(Arrays.asList("1", "2", "3")));
map.put("B", new LinkedHashSet<>(Arrays.asList("4", "5")));
map.put("C", new LinkedHashSet<>(Arrays.asList("6")));

List<String> result = null;
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
    String key = (result == null ? "" : "&") + entry.getKey() + "=";
    Set<String> values = entry.getValue();
    if (values.isEmpty())
        throw new IllegalArgumentException("Empty set not supported");
    List<String> crossJoin = new ArrayList<>((result == null ? 1 : result.size()) * values.size());
    if (result == null)
        for (String value : values)
            crossJoin.add(key + value);
    else
        for (String left : result)
            for (String value : values)
                crossJoin.add(left + key + value);
    result = crossJoin;
}
if (result == null)
    throw new IllegalArgumentException("Empty map not supported");
for (String value : result)
    System.out.println(value);

以下代码可以处理地图的任何大小(空除外),以及每个集合的任何大小(空除外)。空映射/集将引发错误

当然,一旦定义了预期的输出,扩展代码以处理empty应该相当简单

Map<String, Set<String>> map = new LinkedHashMap<>();
map.put("A", new LinkedHashSet<>(Arrays.asList("1", "2", "3")));
map.put("B", new LinkedHashSet<>(Arrays.asList("4", "5")));
map.put("C", new LinkedHashSet<>(Arrays.asList("6")));

List<String> result = null;
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
    String key = (result == null ? "" : "&") + entry.getKey() + "=";
    Set<String> values = entry.getValue();
    if (values.isEmpty())
        throw new IllegalArgumentException("Empty set not supported");
    List<String> crossJoin = new ArrayList<>((result == null ? 1 : result.size()) * values.size());
    if (result == null)
        for (String value : values)
            crossJoin.add(key + value);
    else
        for (String left : result)
            for (String value : values)
                crossJoin.add(left + key + value);
    result = crossJoin;
}
if (result == null)
    throw new IllegalArgumentException("Empty map not supported");
for (String value : result)
    System.out.println(value);

如果您的代码停留一段时间,并且您可能希望更改格式或处理空案例,那么这里的答案更容易阅读,也更易于维护。它自然地处理带有空映射和没有允许值集的键的情况

我假设顺序对您不重要,但您可以用列表替换集合,以获得更可预测/一致的顺序

/**
 * A nested pair class to handle the mappings like A:1.
 */
private static class Pair{
    public Pair(String k,String v){
        this.k = k;
        this.v = v;
    }

    String k;
    String v;

    public String toString(){
        return k+"="+v;
    }
}

/**
 * Given a set like 
 * {{A:"s1",B:"s4","C:s5"}
 * {A:"s1",B:"s4","C:s6"}
 * {A:"s2",B:"s4","C:s5"}
 * {A:"s2",B:"s4","C:s6"}
 * {A:"s3",B:"s4","C:s5"}
 * {A:"s3",B:"s4","C:s6"}}
 * 
 * Converts the contents to string like:
 * A=s1&B=s4&C=s5
 * A=s1&B=s4&C=s6
 * A=s2&B=s4&C=s5
 * A=s2&B=s4&C=s6
 * A=s3&B=s4&C=s5
 * A=s3&B=s4&C=s6
 * @param pairCombinations
 * @return
 */
public static String format(Set<Set<Pair>> pairCombinations){
    String result = "";
    for(Set<Pair> pairSet : pairCombinations){
        result += formatPairSet(pairSet)+"\n";
    }

    return result;
}

private static String formatPairSet(Set<Pair> pairSet) {
    String result = "";
    boolean isFirst = true;
    for(Pair pair : pairSet){
        result+= (isFirst? "" : "&");
        result += pair.k+"="+pair.v;
        isFirst = false;
    }
    return result;
}

/**
 * Given a map of the form:
 * A:{"s1","s2","s3"}
 * B:{"s4"}
 * C:{"s5","s6"}
 * 
 * Will return all possible combinations of pairs in 
 * the map as:
 * {{A:"s1",B:"s4","C:s5"}
 * {A:"s1",B:"s4","C:s6"}
 * {A:"s2",B:"s4","C:s5"}
 * {A:"s2",B:"s4","C:s6"}
 * {A:"s3",B:"s4","C:s5"}
 * {A:"s3",B:"s4","C:s6"}}
 * @param map
 * @return
 */
public static Set<Set<Pair>> getCombinations(Map<String,Set<String>> map){

    Set<Set<Pair>> combinations = new HashSet<Set<Pair>>();
    if(map.entrySet().isEmpty()){
        return combinations;
    }
    combinations.add(new HashSet<Pair>());

    Set<Pair> pairsForKey = null;
    for(Entry<String,Set<String>> mapEntry : map.entrySet()){
        //Ex: {C:"s5",C:"s6"}
        pairsForKey = getPairs(mapEntry);

        //Ex: {{A:s1,B:s4},{A:s2,B:s4},{A:s3,B:s4}}
        combinations = join(combinations,pairsForKey);
    }

    return combinations;
}

private static Set<Pair> getPairs(Entry<String, Set<String>> kWithValidVs) {
    Set<Pair> pairs = new HashSet<Pair>();
    for(String v : kWithValidVs.getValue()){
        pairs.add(new Pair(kWithValidVs.getKey(),v));
    }
    return pairs;
}

/**
 * Given a set of combinations like:
 * {{A:s1,B:s4},{A:s2,B:s4},{A:s3,B:s4}} and a set to join with it like {C:s5,C:s6},
 * will join the set to the existing combinations like:
 * {{A:s1,B:s4,C:s5},{A:s2,B:s4,C:s5},{A:s3,B:s4,C:s5},{A:s1,B:s4,C:s6},{A:s2,B:s4,A:s6},{A:s3,B:s4,C:s6}}
 * @param combinations
 * @param set
 * @return
 */
private static Set<Set<Pair>> join(Set<Set<Pair>> combinations,
        Set<Pair> set) {
    Set<Set<Pair>> join = new HashSet<Set<Pair>>();

    //comment this 'if' if you want keys with empty lists to eliminate all combos.
    if(set.isEmpty()){
        return combinations;
    }

    for(Set<Pair> combo : combinations){
        for(Pair pair : set){
            Set<Pair> newCombo = new HashSet<Pair>();
            newCombo.addAll(combo);
            newCombo.add(pair);
            join.add(newCombo);
        }
    }
    return join;
}

public static void main(String[] args){
    Map<String,Set<String>> map = new HashMap<String,Set<String>>();
    Set<String> aVals = new HashSet<String>();
    aVals.add("1");
    aVals.add("2");
    aVals.add("3");

    Set<String> bVals = new HashSet<String>();
    bVals.add("4");

    Set<String> cVals = new HashSet<String>();
    cVals.add("5");
    cVals.add("6");

    map.put("A", aVals);
    map.put("B", bVals);
    map.put("C", cVals);

    Set<Set<Pair>> combinations =getCombinations(map);
    String printableResult = format(combinations);
    System.out.print(printableResult);
}

如果您的代码停留一段时间,并且您可能希望更改格式或处理空案例,那么这里的答案更容易阅读,也更易于维护。它自然地处理带有空映射和没有允许值集的键的情况

我假设顺序对您不重要,但您可以用列表替换集合,以获得更可预测/一致的顺序

/**
 * A nested pair class to handle the mappings like A:1.
 */
private static class Pair{
    public Pair(String k,String v){
        this.k = k;
        this.v = v;
    }

    String k;
    String v;

    public String toString(){
        return k+"="+v;
    }
}

/**
 * Given a set like 
 * {{A:"s1",B:"s4","C:s5"}
 * {A:"s1",B:"s4","C:s6"}
 * {A:"s2",B:"s4","C:s5"}
 * {A:"s2",B:"s4","C:s6"}
 * {A:"s3",B:"s4","C:s5"}
 * {A:"s3",B:"s4","C:s6"}}
 * 
 * Converts the contents to string like:
 * A=s1&B=s4&C=s5
 * A=s1&B=s4&C=s6
 * A=s2&B=s4&C=s5
 * A=s2&B=s4&C=s6
 * A=s3&B=s4&C=s5
 * A=s3&B=s4&C=s6
 * @param pairCombinations
 * @return
 */
public static String format(Set<Set<Pair>> pairCombinations){
    String result = "";
    for(Set<Pair> pairSet : pairCombinations){
        result += formatPairSet(pairSet)+"\n";
    }

    return result;
}

private static String formatPairSet(Set<Pair> pairSet) {
    String result = "";
    boolean isFirst = true;
    for(Pair pair : pairSet){
        result+= (isFirst? "" : "&");
        result += pair.k+"="+pair.v;
        isFirst = false;
    }
    return result;
}

/**
 * Given a map of the form:
 * A:{"s1","s2","s3"}
 * B:{"s4"}
 * C:{"s5","s6"}
 * 
 * Will return all possible combinations of pairs in 
 * the map as:
 * {{A:"s1",B:"s4","C:s5"}
 * {A:"s1",B:"s4","C:s6"}
 * {A:"s2",B:"s4","C:s5"}
 * {A:"s2",B:"s4","C:s6"}
 * {A:"s3",B:"s4","C:s5"}
 * {A:"s3",B:"s4","C:s6"}}
 * @param map
 * @return
 */
public static Set<Set<Pair>> getCombinations(Map<String,Set<String>> map){

    Set<Set<Pair>> combinations = new HashSet<Set<Pair>>();
    if(map.entrySet().isEmpty()){
        return combinations;
    }
    combinations.add(new HashSet<Pair>());

    Set<Pair> pairsForKey = null;
    for(Entry<String,Set<String>> mapEntry : map.entrySet()){
        //Ex: {C:"s5",C:"s6"}
        pairsForKey = getPairs(mapEntry);

        //Ex: {{A:s1,B:s4},{A:s2,B:s4},{A:s3,B:s4}}
        combinations = join(combinations,pairsForKey);
    }

    return combinations;
}

private static Set<Pair> getPairs(Entry<String, Set<String>> kWithValidVs) {
    Set<Pair> pairs = new HashSet<Pair>();
    for(String v : kWithValidVs.getValue()){
        pairs.add(new Pair(kWithValidVs.getKey(),v));
    }
    return pairs;
}

/**
 * Given a set of combinations like:
 * {{A:s1,B:s4},{A:s2,B:s4},{A:s3,B:s4}} and a set to join with it like {C:s5,C:s6},
 * will join the set to the existing combinations like:
 * {{A:s1,B:s4,C:s5},{A:s2,B:s4,C:s5},{A:s3,B:s4,C:s5},{A:s1,B:s4,C:s6},{A:s2,B:s4,A:s6},{A:s3,B:s4,C:s6}}
 * @param combinations
 * @param set
 * @return
 */
private static Set<Set<Pair>> join(Set<Set<Pair>> combinations,
        Set<Pair> set) {
    Set<Set<Pair>> join = new HashSet<Set<Pair>>();

    //comment this 'if' if you want keys with empty lists to eliminate all combos.
    if(set.isEmpty()){
        return combinations;
    }

    for(Set<Pair> combo : combinations){
        for(Pair pair : set){
            Set<Pair> newCombo = new HashSet<Pair>();
            newCombo.addAll(combo);
            newCombo.add(pair);
            join.add(newCombo);
        }
    }
    return join;
}

public static void main(String[] args){
    Map<String,Set<String>> map = new HashMap<String,Set<String>>();
    Set<String> aVals = new HashSet<String>();
    aVals.add("1");
    aVals.add("2");
    aVals.add("3");

    Set<String> bVals = new HashSet<String>();
    bVals.add("4");

    Set<String> cVals = new HashSet<String>();
    cVals.add("5");
    cVals.add("6");

    map.put("A", aVals);
    map.put("B", bVals);
    map.put("C", cVals);

    Set<Set<Pair>> combinations =getCombinations(map);
    String printableResult = format(combinations);
    System.out.print(printableResult);
}


“你总是有那三把准确的钥匙吗?”路易斯·沃瑟曼-不,钥匙会变。它们不是常数。允许使用外部库吗?@Louis Wasserman-no(输出应该是什么?在屏幕上打印这些组合?放入另一个数据结构(哪一个?)你总是有这三个精确的键吗?@Louis Wasserman-否。键会改变。它们不是常数。允许使用外部库吗?@Louis Wasserman-否:(输出应该是什么?在屏幕上打印这些组合?放入另一个数据结构(哪一个?)这是可行的。我有点被困在for内部。for无法理解如何继续。映射键和值不能为null或空白。此外,我还有另一个问题,即在多集值的情况下,是否有方法确保我们有唯一的值?因为输入是映射和设置的,所有值都是唯一的,除非您的意思是“a=1&B=1”无效。如果你的地图中有三个以上的列表,你可以一次加入两个列表,一直到最后。@Will,但我可能会丢失密钥的数据。我需要这两个数据。多年后,我再次遇到了同样的问题,并用javascript解决了这个问题!这很有效。我有点被困在中间,因为我无法找出如何处理并且映射键和值不能为null或空白。另外,我还有一个问题,即在多集值的情况下,是否有方法确保我们有唯一的值?因为输入是映射和设置的,所有值都是唯一的,除非您的意思是“a=1&B=1”无效。如果您的地图中有三个以上的列表,您可以一次加入两个列表,一直到最后。@Will,但我可能会丢失密钥的数据。我需要这两个数据。多年后我再次遇到同样的问题,并使用javascript解决了此问题!感谢您提供的解决方案。我一定会记住这一点。谢谢您提供的解决方案。我会的一定要记住这一点。