5

I have a for loop which iterates through a maplist and now I want to check every entry of the maplist if it contains a certain String more than once and then delete all Strings except the first one which occurs but I have no clue how to do it.

for (Map<String, String> entry : mapList) {
    String line = "";
    for (String key : entry.keySet()) {
        if (StringUtils.containsAny(key, "5799"){
            line += entry.get(key) + "|";
        }
        list1.add(line);
    }
}

I am thankful for every idea.

6
  • 3
    Exactly twice or at least twice?
    – user6073886
    Commented Aug 1, 2019 at 8:31
  • good question: at least twice Commented Aug 1, 2019 at 8:32
  • Well, you could use Pattern and Matcher to find all matches of the string and replace all but the first with the empty string "".
    – Thomas
    Commented Aug 1, 2019 at 8:36
  • 2
    Another question: would it be a certain string only or any repeated string? Your question seems to indicate you could have input like "a|b|c|a|d|c" - would you want to remove the second a only or the second c as well? To make it easier to understand your requirements, could you provide some examples?
    – Thomas
    Commented Aug 1, 2019 at 8:39
  • I would want to remove any duplicates so the second c as well Commented Aug 1, 2019 at 8:40

3 Answers 3

3

From your comments I assume your requirements are as follows:

  • You have string that contains multiple parts delimited by the pipe character |, e.g. "a|e|b|c|a|c|a|d"
  • You want to remove all repeating strings while preserving the order of elements, e.g. you want "a|e|b|c|d"

To achieve that you could split your string at the pipe, collect the elements into a LinkedHashSet and rejoin the elements using the pipe.

Example using Java 8:

//The pipe needs to be escaped because split() interprets the input as a regex
Set<String> elements = new LinkedHashSet<>( Arrays.asList( input.split( "\\|" ) ) );
//rejoin using the pipe
String output = elements.stream().collect( Collectors.joining( "|" ) );
2

To see if key contains a string s at least twice, and to remove the second occurrence, use indexOf twice, with the second call starting the search after the first occurrence:

static String removeSecond(String key, String s) {
    int idxFirst = key.indexOf(s);
    if (idxFirst != -1) {
        int idxSecond = key.indexOf(s, idxFirst + s.length());
        if (idxSecond != -1) {
            return key.substring(0, idxSecond) +
                   key.substring(idxSecond + s.length());
        }
    }
    return key; // Nothing to remove
}

Test

System.out.println(removeSecond("mississippi", "ss")); // prints: missiippi
System.out.println(removeSecond("mississippi", "i"));  // prints: missssippi
System.out.println(removeSecond("mississippi", "pp")); // prints: mississippi

UPDATE

If you want to remove all duplicates, i.e. leave only the first occurrence, keep searching. For best performance of building the new string, use StringBuilder.

static String removeDuplicates(String key, String s) {
    int idx = key.indexOf(s);
    if (idx == -1)
        return key; // Nothing to remove
    StringBuilder buf = new StringBuilder();
    int prev = 0;
    for (int start = idx + s.length(); (idx = key.indexOf(s, start)) != -1; prev = start = idx + s.length())
        buf.append(key.substring(prev, idx));
    return (prev == 0 ? key : buf.append(key.substring(prev)).toString());
}

Test

System.out.println(removeDuplicates("mississippi", "ss")); // prints: missiippi
System.out.println(removeDuplicates("mississippi", "i"));  // prints: misssspp
System.out.println(removeDuplicates("mississippi", "s"));  // prints: misiippi
System.out.println(removeDuplicates("mississippi", "ab")); // prints: mississippi
1

If you want to remove all occurrences except the first one:

public static String removeExceptFirst(String master, String child) throws Exception {
    int firstIndex = master.indexOf(child);
    int lastIndexOf = master.lastIndexOf(child);
    if (firstIndex == lastIndexOf) {
        if (firstIndex == -1) {
            throw new Exception("No occurrence!");
        } else {
            throw new Exception("Only one occurrence!");
        }
    }

    while (true) {
        firstIndex = master.indexOf(child);
        lastIndexOf = master.lastIndexOf(child);
        if (firstIndex == lastIndexOf) {
            return master;
        }
        master = master.substring(0, lastIndexOf) + master.substring(child.length() + lastIndexOf);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.