Как удалить повторяющиеся элементы из ArrayList?

Я столкнулся с той же проблемой, и я нашел для нее решение. Я сначала добавил все файлы в центральный репозиторий (также разработчики).

Так что если разработчик извлекает файлы из репозитория, там также присутствует конфиг разработчика. При изменении этого файла Git не должен знать об этих изменениях. Таким образом, изменения не могут быть перенесены / зафиксированы в репозиторий, но остаются локально.

Я решил это с помощью команды git: update-index --assume-unchanged. Я создал файл bat, который выполняется в предварительной структуре проектов, содержащих файл, изменения которого должны игнорироваться Git. Вот код, который я вложил в файл bat:

IF NOT EXIST %2%\.git GOTO NOGIT
set fileName=%1
set fileName=%fileName:\=/%
for /f "useback tokens=*" %%a in ('%fileName%') do set fileName=%%~a
set "gitUpdate=git update-index --assume-unchanged"
set parameter= "%gitUpdate% %fileName%"
echo %parameter% as parameter for git
"C:\Program Files (x86)\Git\bin\sh.exe" --login -i -c %parameter%
echo Make FIleBehaveLikeUnchangedForGit Done.
GOTO END
:NOGIT
echo no git here.
echo %2%
:END

В моей предварительной сборке я сделал бы вызов в файл bat, например:

call "$(ProjectDir)\..\..\MakeFileBehaveLikeUnchangedForGit.bat" "$(ProjectDir)Web.config.developer" "$(SolutionDir)"

Я нашел SO - файл bat, который копирует правильный файл конфигурации в файл web.config / app.config. Я также называю этот файл bat в prebuild. Код для этого файла bat:

@echo off
echo Comparing two files: %1 with %2
if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound
fc %1 %2 
if %ERRORLEVEL%==0 GOTO NoCopy
echo Files are not the same.  Copying %1 over %2
copy %1 %2 /y & goto END
:NoCopy
echo Files are the same.  Did nothing
goto END
:File1NotFound
echo %1 not found.
goto END
:File2NotFound
copy %1 %2 /y
goto END
:END
echo Done.

В моей предварительной загрузке я сделал бы вызов файла bat, например:

call "$(ProjectDir)\..\..\copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config
463
задан Andrew Tobilko 23 October 2018 в 08:35
поделиться

5 ответов

Если Вы не хотите дубликаты в Collection, необходимо рассмотреть, почему Вы используете Collection, который позволяет дубликаты. Самый легкий способ удалить повторенные элементы состоит в том, чтобы добавить содержание к Set (который не позволит дубликаты), и затем добавьте Set назад к ArrayList:

Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);

, Конечно, это уничтожает упорядочивание элементов в ArrayList.

947
ответ дан Ivar 23 October 2018 в 08:35
поделиться

Как сказано прежде, необходимо использовать класс, реализовывая интерфейс Set вместо Списка, чтобы быть уверенными в уникальности элементов. Если необходимо сохранить порядок элементов, интерфейс SortedSet может тогда использоваться; реализации класса TreeSet тот интерфейс.

1
ответ дан Yoon5oo 23 October 2018 в 08:35
поделиться

Если Вы не хотите дубликаты, используйте Набор вместо List. Для преобразования List в Set, можно использовать следующий код:

// list is some List of Strings
Set<String> s = new HashSet<String>(list);

, Если действительно необходимый можно использовать ту же конструкцию для преобразования Set назад в List.

53
ответ дан Benno Richters 23 October 2018 в 08:35
поделиться

Вероятно, немного излишества, но я наслаждаюсь этим видом изолированной проблемы.:)

Этот код использует временный Набор (для проверки уникальности), но удаляет элементы непосредственно в исходном списке. Так как удаление элемента в ArrayList может вызвать огромный объем копирования массива, удалить (интервал) - метода избегают.

public static <T> void removeDuplicates(ArrayList<T> list) {
    int size = list.size();
    int out = 0;
    {
        final Set<T> encountered = new HashSet<T>();
        for (int in = 0; in < size; in++) {
            final T t = list.get(in);
            final boolean first = encountered.add(t);
            if (first) {
                list.set(out++, t);
            }
        }
    }
    while (out < size) {
        list.remove(--size);
    }
}

, В то время как мы в нем, вот версия для LinkedList (намного более хороший!):

public static <T> void removeDuplicates(LinkedList<T> list) {
    final Set<T> encountered = new HashSet<T>();
    for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
        final T t = iter.next();
        final boolean first = encountered.add(t);
        if (!first) {
            iter.remove();
        }
    }
}

Использование маркер взаимодействуют через интерфейс для представления унифицированного решения для Списка:

public static <T> void removeDuplicates(List<T> list) {
    if (list instanceof RandomAccess) {
        // use first version here
    } else {
        // use other version here
    }
}

РЕДАКТИРОВАНИЕ: Я предполагаю, что материал дженериков действительно не добавляет значения здесь.. О, хорошо.:)

12
ответ дан volley 23 October 2018 в 08:35
поделиться

Хотя преобразование ArrayList к HashSet эффективно удаляет дубликаты, если необходимо сохранить порядок вставки, я предложил бы, чтобы Вы использовали этот вариант

// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);

Затем если необходимо возвратиться List ссылка, можно использовать снова конструктора преобразования.

286
ответ дан IgorGanapolsky 23 October 2018 в 08:35
поделиться
  • 1
    ... риск является определенно не нолем. – Robert MacLean 13 March 2009 в 06:33
Другие вопросы по тегам:

Похожие вопросы: