Reputation: 353
I have string with value as ||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||
I am trying to write code which should remove duplicates and return the unique values retaining the demiliters like this ||HelpDesk||IT Staff||Admin||Audit||
My code is using HashSet to remove duplicates but the problem is it is removing delimiters. How can I retain delimiters by removing duplicate values only.
Below is my code after removing duplicates and adding back delimiters. But not sure if there is easy way of doing this.
public static void main(String[] args) {
TestDuplicates testDuplicates = new TestDuplicates();
String bRole = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
List<String> listWithoutDuplicates = new ArrayList<String>();
String noDup = "";
List<String> splittedStringList =
new ArrayList<String>();
SplitOperations splitOperations =
new SplitOperations();
splittedStringList =
splitOperations.splitString(bRole);
for (int i = 0; i < splittedStringList.size(); i++) {
HashSet<String> listToSet = new HashSet<String>(splittedStringList);
listWithoutDuplicates = new ArrayList<String>(listToSet);
}
for(int i=0;i<listWithoutDuplicates.size();i++){
noDup = noDup + "||"+listWithoutDuplicates.get(i);
System.out.println(listWithoutDuplicates.get(i));
}
System.out.println("No Duplicate is::"+ noDup+"||");
}
Thanks
Upvotes: 1
Views: 3027
Reputation: 425238
Here's a regex-based one liner:
str = str.replaceAll("(\\|[^|]+)(?=.*\\1\\|)", "");
This works by replacing every term that is followed by itself somewhere ahead via a look ahead assertion that uses a back reference.
Here's a non-regex java 8 one liner:
Arrays.stream(str.substring(1).split("[|]")).distinct().collect(Collectors.joining("|", "|", "|"));
Upvotes: 0
Reputation: 9413
Using Guava lib it's a one liner:
Joiner.on("||").skipNulls(Splitter.on("||").trimResults().split(<target_string>);)
Here is my attempt at it:
import java.util.*;
public class Seperator {
public static void main(String[] args) {
String bRole = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
List<String> listWithoutDuplicates = new ArrayList<String>();
String noDup = "";
List<String> splittedStringList = new ArrayList<String>();
splittedStringList = Arrays.asList(bRole.split("\\|\\|"));
LinkedHashSet<String> listToSet = new LinkedHashSet<String>(splittedStringList);
noDup = Seperator.join(listToSet, "||");
System.out.println("No Duplicate is::"+ noDup+"||");
}
public static String join(Set<String> set, String sep) {
String result = null;
if(set != null) {
StringBuilder sb = new StringBuilder();
Iterator<String> it = set.iterator();
if(it.hasNext()) {
sb.append(it.next());
}
while(it.hasNext()) {
sb.append(sep).append(it.next());
}
result = sb.toString();
}
return result;
}
}
LinkedHashSet are mainly used to preserve the order and ofcourse get uniques elements. Joining is pretty standard, but we can use Google's Guava Library also (Joiner):
So, instead of Seperator.join(listToSet, "||");
You'll have: Joiner.on("||").join(listToSet);
Upvotes: 0
Reputation: 1124
This should work, also it will maintain sequence of elements if you want. Note that I have not written code to put delimiters again.
public static void main(String s[]){
String a = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
a = a.replaceAll("\\|\\|",",");
String arr[] = a.split(",");
//linked hash set in case you want to maintain the sequence of elements
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr));
set.remove("");
System.out.println(set);
//Iterate through the set and put your delimiters here again
}
Upvotes: 0
Reputation: 93872
You could use a LinkedHashSet
to preserve insertion order. Once you splitted the String by "||" just add the delimiters when constructing back the String.
String s = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
Set<String> set = new LinkedHashSet<>(Arrays.asList(s.split(Pattern.quote("||"))));
String noDup = "||";
for(String st : set) {
if(st.isEmpty()) continue;
noDup += st+"||";
}
Or using the new java 8 Stream API :
String noDup = "||"+
Arrays.stream(s.split(Pattern.quote("||")))
.distinct()
.filter(st -> !st.isEmpty()) //we need to remove the empty String produced by the split
.collect(Collectors.joining("||"))+"||";
Both approaches yield the same result (||HelpDesk||IT Staff||Admin||Audit||
).
Upvotes: 1
Reputation: 1280
public String removeDublicate () {
String str = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
String split[] = str.split("\\|\\|");
String newStr = "";
for (String s : split) {
if (!s.isEmpty() && !newStr.contains(s)) {
newStr += "||" + s;
}
}
newStr += "||";
return newStr;
}
Something like that? str
could be an argument.
Edit #1
If you want to get rid of && !newStr.contains(s)
you can use a HashSet<String>
instead. I think that is overkill however. .contains(s)
will do the trick when the string is small such as this.
Upvotes: 0