简体   繁体   English

用 Map 值中的字符串替换 Map 键中的字符串

[英]Replace string in Map key with string from Map value

I have this code我有这个代码

import java.util.*;

public class Tester {
public static void main(String[] args) {

    HashMap<String, String> data=new HashMap();
    data.put("Chance to Avoid Fire Damage when Hit", "(3-7)%");
    data.put("Chance to Avoid Cold Damage when Hit", "(6-8)%");
    data.put("Chance to Avoid Chaos Damage when Hit", "(6-7)%");
    data.put("Adds # to # Fire Damage to Spells", "{\"min\":10,\"avg\":20,\"max\":30}");
    data.put("Adds # to # Cold Damage to Curses", "{\"avg\":20,\"max\":30,\"min\":10}");
    data.put("Adds # to # Cold Damage to Curses", "{\"avg\":30,\"max\":20,\"min\":40}");
    data.put("Adds # to # Physical Damage to Weapon", "{\"min\":8,\"max\":32,\"avg\":20}");
    data.put("Curse Enemies with Vulnerability on level", "30");

}
}

our teacher asked us to make a method that will replace each first "#" with his min value and the second "#" with the max value ex : "Adds 10 to 30 Fire Damage to Spells..." I've been doing it wrong for few hours and really need some help this is what i've done this far (I know its probably bad):我们的老师要求我们制作一种方法,将第一个“#”替换为他的最小值,将第二个“#”替换为最大值,例如:“对法术增加 10 到 30 火焰伤害……”我一直在做它错误了几个小时,真的需要一些帮助,这就是我到目前为止所做的(我知道它可能很糟糕):

public class Exe2 {
public static String replaceH(Map<String, String> mods) {
    Set<String> modss = new HashSet();
    String z="";
    String[] keys = mods.keySet().toArray(new String[0]);
    String key = mods.get(keys);
    for (String n : keys) {
        if(n.contains("#")){
           z= n.replace("#",key.indexOf(5));

        }
    }
    return z;
}

}

Would really appreciate your help,thank you :)非常感谢您的帮助,谢谢:)

You have to remove the old keys with a hash sign # , in a loop.您必须循环删除带有哈希符号#的旧键。 And insert the key with replacements from the value.并插入带有替换值的键。

As in a loop removing and inserting at the same time may be problematic, you could build a second map with the new results, or the other way round, copy the (concerning) keys from the original map first.由于在循环中同时删除和插入可能会出现问题,您可以使用新结果构建第二张地图,或者反过来,首先从原始地图复制(有关)键。

To retrieve from the value minimum and maximum, one could use a regular expression pattern matching: value.replaceFirst("...", "$1");要从最小值和最大值中检索,可以使用正则表达式模式匹配: value.replaceFirst("...", "$1"); or more difficult value.indexOf("max") / substring或更难的value.indexOf("max") / substring

First of all you should use respeated keys in a map so that's why I obtain three output instead of 4.首先,您应该在地图中使用重复的键,这就是为什么我获得三个输出而不是 4 个的原因。

Secondly in order to make the problem more simple you should use the same pattern:其次,为了使问题更简单,您应该使用相同的模式:

package tests;
import java.util.*;
public class Tester {

    public static void main(String[] args) {
        getFinal(initial(data));

    }
public static Map<String,String> initial(Map<String,String>a){
          a.put("Chance to Avoid Fire Damage when Hit","(3-7)%");
          a.put("Chance to Avoid Cold Damage when Hit", "(6-8)%");
          a.put("Chance to Avoid Chaos Damage when Hit", "(6-7)%");
          a.put("Adds # to # Fire Damage to Spells", "{\"avg\":20,\"max\":30,\"min\":10}");
          a.put("Adds # to # Cold Damage to Curses", "{\"avg\":20,\"max\":30,\"min\":10}");
          a.put("Adds # to # Cold Damage to Curses", "{\"avg\":30,\"max\":20,\"min\":40}");
          a.put("Adds # to # Physical Damage to Weapon", "{\"avg\":20,\"max\":32,\"min\":8}");
          a.put("Curse Enemies with Vulnerability on level", "30");
          return a;
      }

 public static Map<String,String>getFinal(Map<String,String>b){
         List<String>aux=new ArrayList<String>(b.keySet());
         List<String>aux1=new ArrayList<String>(b.keySet());
         for(int i=0;i<b.size();i++){
             if(aux.get(i).contains("#")){
                 String min=b.get(aux.get(i)).split(",")[2];
                 String max=b.get(aux.get(i)).split(",")[1];
                 String minVal=min.split(":")[1].replace("}","").trim();
                 String maxVal=max.split(":")[1].trim();
                 String c=aux.get(i).replaceFirst("#",minVal);
                 String d=c.replaceAll("#",maxVal);
                 System.out.println(d);
                 b.replace(aux1.get(i),c);

             }
             }

             return b;
         }
}

Output:输出:

Adds 40 to 20 Cold Damage to Curses
Adds 8 to 32 Physical Damage to Weapon
Adds 10 to 30 Fire Damage to Spells

You can try this你可以试试这个

public class ChangeMapKeysWithValue {

    public static void main(String[] args) {

        HashMap<String, String> data=new HashMap<String, String>();
        HashMap<String, String> newData=new HashMap<String, String>();
        data.put("Chance to Avoid Fire Damage when Hit", "(3-7)%");
        data.put("Chance to Avoid Cold Damage when Hit", "(6-8)%");
        data.put("Chance to Avoid Chaos Damage when Hit", "(6-7)%");
        data.put("Adds # to # Fire Damage to Spells", "{\"min\":10,\"avg\":20,\"max\":30}");
        data.put("Adds # to # Cold Damage to Curses", "{\"avg\":20,\"max\":30,\"min\":10}");
        data.put("Adds # to # Cold Damage to Curses", "{\"avg\":30,\"max\":20,\"min\":40}");
        data.put("Adds # to # Physical Damage to Weapon", "{\"min\":8,\"max\":32,\"avg\":20}");
        data.put("Curse Enemies with Vulnerability on level", "30");

        Set<String> keySet = data.keySet();
        Iterator<String> itr = keySet.iterator();

        while(itr.hasNext()) {

            String key = itr.next();
            String value = data.get(key);

            if(key.contains("#")) {

                String[] valueArray = value.substring(1, value.length()-1).split(",");

                Map<String, String> valueSplitMap = new HashMap<String, String>();
                valueSplitMap.put(valueArray[0].split(":")[0], valueArray[0].split(":")[1]);
                valueSplitMap.put(valueArray[1].split(":")[0], valueArray[1].split(":")[1]);
                valueSplitMap.put(valueArray[2].split(":")[0], valueArray[2].split(":")[1]);

                key = key.replace("#", valueSplitMap.get("\"min\""));
                key = key.replace("to " + valueSplitMap.get("\"min\""), "to " + valueSplitMap.get("\"max\""));                          
            }
            if(key != null && !key.isEmpty()) {

                newData.put(key, value);
            }
        }

        System.out.println(newData);
    }
}

Usually you souldn't never change the original object , so could be a good pratice use it like a read only object and get the result in a new object , anyway my implementation is using json library java-json.jar that you can integrate to your project , and may you can show to your prof.通常你永远不会改变原始对象,所以可能是一个很好的实践,像只读对象一样使用它并在新对象中获得结果,无论如何我的实现是使用你可以集成到的 json 库java-json.jar你的项目,你可以展示给你的教授。 I am sure he can appreciate it .我相信他会欣赏的。

Below the code (shows only the result):代码下方(仅显示结果):

import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;


public class Tester {

    public Tester() {
        // TODO Auto-generated constructor stub
    }

    public static String replaceAt(String s,int pos,String val) {
        return s.substring(0, pos) + val + s.substring(pos + 1);
      }

    public static void main(String[] args) throws JSONException {
        // TODO Auto-generated method stub

        HashMap<String, String> data=new HashMap();
        HashMap<String, String> result=new HashMap();
        data.put("Chance to Avoid Fire Damage when Hit", "(3-7)%");
        data.put("Chance to Avoid Cold Damage when Hit", "(6-8)%");
        data.put("Chance to Avoid Chaos Damage when Hit", "(6-7)%");
        data.put("Adds # to # Fire Damage to Spells", "{\"min\":10,\"avg\":20,\"max\":30}");
        data.put("Adds # to # Cold Damage to Curses", "{\"avg\":20,\"max\":30,\"min\":10}");
        data.put("Adds # to # Cold Damage to Curses", "{\"avg\":30,\"max\":20,\"min\":40}");
        data.put("Adds # to # Physical Damage to Weapon", "{\"min\":8,\"max\":32,\"avg\":20}");
        data.put("Curse Enemies with Vulnerability on level", "30");

        String[] keys = data.keySet().toArray(new String[0]);   
        for (String n : keys) {
            String value2 ="";
            String value ="";
            if(n.contains("#")){
                value = data.get(n);        
            JSONObject object = new JSONObject(value);
            String[] valuekeys = JSONObject.getNames(object);
            int cont =0;
            for (String key2 : valuekeys)
            {
                if("min".equals(key2)){
                     value2 =object.get(key2).toString();
                    int pos = n.indexOf("#");               
                     n=replaceAt(n, pos, value2);
                }
                 if("max".equals(key2)){
                      value2 =object.get(key2).toString();
                     int pos = n.lastIndexOf("#");           
                    n= replaceAt(n, pos, value2);
                } 

            }
             System.out.println(n); 

        }   
        }

    }
}

by using groovy:通过使用常规:

Map<String, String> reference = [
    '1' : 'apple'  ,
    '2' : 'banana' ,
    '3' : 'pears'  ,
    '4' : 'peach'
]

'I want 1 she wants 4'.tokenize(' ')
                      .collect { references.get(it) ?: it }
                      .join(' ')

// result:
I want apple she wants peach

Or using following to keep the string format或者使用以下来保持字符串格式

'I like    1, she    likes    3.'
    .replaceAll("[^\\w]", "_\$0")
    .split('_')
    .collect {
        String c = it.trim()
        reference.get(c) ? it.replace(c, reference.get(c)) : it
     }
    .join()

// Result: I like    apple, she    likes    pears.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM