2014-12-06 8 views
1

У меня есть строка со значением как || HelpDesk || ИТ-персонал || ИТ-персонал || Администратор || Аудит || HelpDesk ||Как удалить повторяющиеся значения в строке с разделителями

Я пытаюсь написать код, который должен удалять дубликаты и возвращать уникальные значения, сохраняющие такие демилитаторы, как это || HelpDesk || IT Staff || Admin || Audit ||

Мой код использует HashSet для удаления дубликатов, но проблема заключается в удалении разделителей. Как сохранить разделители, удалив только повторяющиеся значения.

Ниже мой код после удаления дубликатов и добавления разделителей. Но не уверен, есть ли простой способ сделать это.

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+"||"); 


} 

Благодаря

+0

Разделить строки на '' || (вы должны избегайте этих символов tho или используя 'Pattern.quote'). Вы можете вернуть разделитель при построении String из элементов в Set. –

+0

Можем ли мы знать, что вы пробовали до сих пор? – SMA

+0

Рассмотрите возможность добавления разделителей обратно после извлечения уникальных элементов из HashSet. – user314104

ответ

1

Чтобы сохранить порядок вставки, вы можете использовать LinkedHashSet. Как только вы разделили строку на «||» просто добавьте разделители при построении назад строки.

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+"||"; 
} 

Или с помощью нового Java API 8 Поток:

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("||"))+"||"; 

Оба подхода дают одинаковый результат (||HelpDesk||IT Staff||Admin||Audit||).

0
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; 
} 

Нечто подобное? str может быть аргументом.

Редактировать # 1

Если вы хотите избавиться от && !newStr.contains(s) вы можете использовать HashSet<String> вместо этого. Я думаю, что это перебор. .contains(s) будет делать трюк, когда строка такая маленькая.

0

Это должно работать, также оно будет поддерживать последовательность элементов, если вы хотите. Обратите внимание, что я еще не написал код, чтобы снова установить разделители.

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 
    } 
0

Вот регулярное выражение на основе один лайнер:

str = str.replaceAll("(\\|[^|]+)(?=.*\\1\\|)", ""); 

Это работает, заменив каждый термин, который следует по себе где-то впереди через прогностическое утверждение, которое использует обратную ссылку.

Вот не-регулярное выражение Java 8 один лайнер:

Arrays.stream(str.substring(1).split("[|]")).distinct().collect(Collectors.joining("|", "|", "|")); 
0

Использование Guava lib это один лайнер:

Joiner.on("||").skipNulls(Splitter.on("||").trimResults().split(<target_string>);) 

Вот моя попытка на него:

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 в основном используются для сохранения порядка и, конечно же, получения уникальных элементов.Присоединение является довольно стандартным, но мы можем использовать Google's Guava Library также (Столяр):

Таким образом, вместо Seperator.join(listToSet, "||");

Вы будете иметь: Joiner.on("||").join(listToSet);