在IntelliJ中替换双大括号初始化

huangapple go评论69阅读模式
英文:

Replace double brace initialisation in IntelliJ

问题

以下是翻译好的内容:

我正在尝试重构我们项目之一的代码,该代码广泛使用了双括号初始化。我可以自由地(可变性不是问题)利用com.google.common.collect.ImmutableMap来初始化这些映射。由于有100多个用法,我想摆脱手动编辑。

在IntelliJ中是否有一种有效的方法可以替换完整的代码块,如下所示:

Map<**> mapOfAnyTypeKeyToAnyTypeValue = new HashMap<**>(){{
    putkey1value1;
    putkey2value2;
}};

替换为类似以下的内容:

Map<**> mapOfAnyTypeKeyToAnyTypeValue = ImmutableMap.of
    key1value1
    key2value2
;

当然,条目的数量可能会有所不同,可能需要使用正则表达式。但是我对基于正则表达式的在IntelliJ中进行替换并不太熟悉。

如果有帮助的话,我使用的是IntelliJ IDEA 2020.2.3 Preview(Community Edition)。

英文:

I am trying to refactor the code for one of our projects which has extensively used double brace initialisation. I have a liberty(mutability is not a concern) of making use of com.google.common.collect.ImmutableMap to initialse these Map. Since there are more than 100+ usage, I wanted to do away with manual edits here.

Is there a way to effectively replace a complete code block in IntelliJ such as the following:

Map&lt;*, *&gt; mapOfAnyTypeKeyToAnyTypeValue = new HashMap&lt;*, *&gt;() {{
    put(key1, value1);
    put(key2, value2);
}};

to something of the likes

Map&lt;*, *&gt; mapOfAnyTypeKeyToAnyTypeValue = ImmutableMap.of(
    key1, value1, 
    key2, value2);

Ofcourse the size of entries could vary and a regular expression here might be needed. But I am not very friendly with the regex based replaces in IntelliJ.

If it could be of any help, I am using IntelliJ IDEA 2020.2.3 Preview (Community Edition).

答案1

得分: 1

很遗憾,IntelliJ的正则表达式处理器不允许在匹配的组中使用多个反向引用,并且只会捕获特定组的最后一个值,因此您可以通过逐个处理每个文件部分来实现您的目标。我认为这种方法耗时,但足够安全,因为您可以在现场验证替换。

以下是如何实现目标的演示:

这是我使用的示例类:
在IntelliJ中替换双大括号初始化

  1. 在整个项目范围内搜索并替换正则表达式模式(会强制执行构建失败,并突出显示所有需要修复的位置。在继续之前,最好先全部检查一遍):
    在IntelliJ中替换双大括号初始化

步骤2和3应逐个重复处理每个声明块!

  1. 选择包含put声明的块,并为正则表达式模式进行搜索和替换(在选择范围内进行 - 我添加的截屏是按类别进行的,但这是不正确的!)
    在IntelliJ中替换双大括号初始化

  2. 选择闭合大括号并手动修复它们。
    在IntelliJ中替换双大括号初始化

以下是演示使用的代码和生成的代码:

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

public class Main
{
    public static void main(String[] args)
    {
        Map&lt;Object, Object&gt; aMap = new HashMap&lt;Object, Object&gt;() {{
            put(&quot;1&quot;, &#39;a&#39;);
            put(2, &quot;b&quot;);
            put(BigInteger.valueOf(3L), new char[3]);
        }};
    }
}

转换为:

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

public class Main
{
    public static void main(String[] args)
    {
        Map&lt;Object, Object&gt; aMap = ImmutableMap.of(
            &quot;1&quot;, &#39;a&#39;, 2, &quot;b&quot;, BigInteger.valueOf(3L), new char[3]);
    }
}

用于步骤1的正则表达式:new HashMap&lt;\\w+,\\s*\\w+&gt;\\(\\)\\s*\\{\\{ -> ImmutableMap.of(
用于步骤2的正则表达式:put\\((.*)\\,\\s*(.*)\\)\\;\\s+ -> $1, $2,

您还需要手动修复类导入。

附注:可以编写脚本来执行此操作,但通常以编程方式处理代码库不是一个好的做法。

英文:

Unfortunatelly IntelliJ regex processor does not allow multiple backreferences per matched group and will capture only the last value for that particular group, therefore you could achieve your goal by processing each file part by part. I find this approach time consuming yet safe enough as you can verify replacements at place.

Here is a demo of how could one achieve the goal:

This will be the sample class that I'm using:
在IntelliJ中替换双大括号初始化

  1. Search & Replace all occurrances for regex pattern (project wise - enforces build failures and will highlight all the places that has to be fixed. A good idea is to check all before continuing forward):
    在IntelliJ中替换双大括号初始化

> Steps from 2 and 3 should be repeated per declaration block individually!

  1. Select the block that contains the put declarations and Search & Replace for regex pattern(selection wise - the screenshot that I added does this class wise but it isn't correct!)
    在IntelliJ中替换双大括号初始化

  2. Select the closing curly brackets and manually fix them.
    在IntelliJ中替换双大括号初始化

Here is the code used for the demo and the resulting code:

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

public class Main
{
    public static void main(String[] args)
    {
        Map&lt;Object, Object&gt; aMap = new HashMap&lt;Object, Object&gt;() {{
            put(&quot;1&quot;, &#39;a&#39;);
            put(2, &quot;b&quot;);
            put(BigInteger.valueOf(3L), new char[3]);
        }};
    }
}

transformed to:

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

public class Main
{
    public static void main(String[] args)
    {
        Map&lt;Object, Object&gt; aMap = ImmutableMap.of(
            &quot;1&quot;, &#39;a&#39;, 2, &quot;b&quot;, BigInteger.valueOf(3L), new char[3]);
    }
}

Regex used for step 1: new HashMap&lt;\w+,\s*\w+&gt;\(\)\s*\{\{ -> ImmutableMap.of( <br/>
Regex used for step 2: put\((.*)\,\s*(.*)\)\;\s+ -> $1, $2,

You will have to manually fix class imports as well.

P.S. One could write a script to do this, but generally it's not a good practice to process your codebase programatically.

huangapple
  • 本文由 发表于 2020年9月24日 15:36:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64041598.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定