public static String compareMd5ResultString(List<String> changedGroupKeys) throws IOException {
        if (null == changedGroupKeys) {
            return "";
        }
        
        StringBuilder sb = new StringBuilder();
        
        for (String groupKey : changedGroupKeys) {
            String[] dataIdGroupId = GroupKey2.parseKey(groupKey);
            sb.append(dataIdGroupId[0]);
            sb.append(WORD_SEPARATOR);
            sb.append(dataIdGroupId[1]);
            // if have tenant, then set it
            if (dataIdGroupId.length == 3) {
                if (StringUtils.isNotBlank(dataIdGroupId[2])) {
                    sb.append(WORD_SEPARATOR);
                    sb.append(dataIdGroupId[2]);
                }
            }
            sb.append(LINE_SEPARATOR);
        }
        
        // To encode WORD_SEPARATOR and LINE_SEPARATOR invisible characters, encoded value is %02 and %01
        return URLEncoder.encode(sb.toString(), "UTF-8");
    }
@Test
    void testCompareMd5ResultString() {
        
        final MockedStatic<GroupKey2> groupKey2MockedStatic = Mockito.mockStatic(GroupKey2.class);
        
        List<String> changedGroupKeys = new ArrayList<>();
        changedGroupKeys.add("test");
        
        String[] arr = new String[3];
        arr[0] = "test0";
        arr[1] = "test1";
        arr[2] = "test2";
        when(GroupKey2.parseKey(anyString())).thenReturn(arr);
        
        try {
            String actualValue = MD5Util.compareMd5ResultString(changedGroupKeys);
            assertEquals("test0%02test1%02test2%01", actualValue);
        } catch (IOException e) {
            System.out.println(e.toString());
        }
        
        groupKey2MockedStatic.close();
    }