Компиляция программы на C ++ выполняется в несколько этапов, как указано в 2.2 (кредиты для Кейта Томпсона для ссылки) :
Превалирование среди правил синтаксиса
- Физические символы исходного файла сопоставляются в соответствии с реализацией в соответствии с базовым набором символов источника (ввод символов новой строки для индикаторов конца строки) при необходимости. [SNIP]
- Каждый экземпляр символа обратной косой черты (\), за которым сразу следует символ новой строки, удаляется, сплайсируя физические исходные строки для формирования логических строк источника. [SNIP]
- Исходный файл разбивается на токены предварительной обработки (2.5) и последовательности символов пробела (включая комментарии). [SNIP]
- Выполнены предпроцессорные директивы, макро-вызовы разворачиваются и выполняются операторные выражения _Pragma. [SNIP]
- Каждый элемент набора символов в символьном литерале или строковый литерал, а также каждая escape-последовательность и универсальное имя-символа в символьном литерале или не- -raw строковый литерал, преобразуется в соответствующий член набора символов выполнения; [SNIP]
- Соединительные маркеры литералов строки объединены.
- Символы пробела, разделяющие токены, уже не являются значимыми. Каждый токен предварительной обработки преобразуется в токен. (2.7). Результирующие маркеры синтаксически и семантически анализируются и переводятся как единица перевода. [SNIP]
- Устанавливаемые единицы перевода и единицы экземпляра объединяются следующим образом: [SNIP]
- Все ссылки на внешние сущности решена. Компоненты библиотеки связаны для удовлетворения внешних ссылок на объекты, не определенные в текущем переводе. Весь такой переводчик выводится в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения. (акцент мой)
[footnote] Реализации должны вести себя так, как если бы эти отдельные фазы происходили, хотя на практике различные фазы могли быть свернуты вместе.
Указанные ошибки возникают на этом последнем этапе компиляции, чаще всего называемом связыванием. Это в основном означает, что вы собрали кучу файлов реализации в объектные файлы или библиотеки, и теперь вы хотите заставить их работать вместе.
Скажите, что вы определили символ
a
вa.cpp
. Теперьb.cpp
объявил этот символ и использовал его. Перед связыванием он просто предполагает, что этот символ был определен где-то , но он пока не заботится о том, где. Фаза связывания отвечает за поиск символа и правильную привязку его кb.cpp
(ну, собственно, к объекту или библиотеке, которая его использует).Если вы используете Microsoft Visual Studio, вы будете см., что проекты генерируют файлы
.lib
. Они содержат таблицу экспортированных символов и таблицу импортированных символов. Импортированные символы разрешены против библиотек, на которые вы ссылаетесь, и экспортированные символы предоставляются для библиотек, которые используют этот.lib
(если есть).Подобные механизмы существуют для других компиляторов / платформ.
Общие сообщения об ошибках:
error LNK2001
,error LNK1120
,error LNK2019
для Microsoft Visual Studio иundefined reference to
symbolName для GCC.Код:
struct X { virtual void foo(); }; struct Y : X { void foo() {} }; struct A { virtual ~A() = 0; }; struct B: A { virtual ~B(){} }; extern int x; void foo(); int main() { x = 0; foo(); Y y; B b; }
генерирует следующие ошибки с GCC:
/home/AbiSfw/ccvvuHoX.o: In function `main': prog.cpp:(.text+0x10): undefined reference to `x' prog.cpp:(.text+0x19): undefined reference to `foo()' prog.cpp:(.text+0x2d): undefined reference to `A::~A()' /home/AbiSfw/ccvvuHoX.o: In function `B::~B()': prog.cpp:(.text._ZN1BD1Ev[B::~B()]+0xb): undefined reference to `A::~A()' /home/AbiSfw/ccvvuHoX.o: In function `B::~B()': prog.cpp:(.text._ZN1BD0Ev[B::~B()]+0x12): undefined reference to `A::~A()' /home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1Y[typeinfo for Y]+0x8): undefined reference to `typeinfo for X' /home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1B[typeinfo for B]+0x8): undefined reference to `typeinfo for A' collect2: ld returned 1 exit status
и аналогичные ошибки с Microsoft Visual Studio:
1>test2.obj : error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ) 1>test2.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA) 1>test2.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ) 1>test2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall X::foo(void)" (?foo@X@@UAEXXZ) 1>...\test2.exe : fatal error LNK1120: 4 unresolved externals
. Общие причины включают в себя:
- Не удалось связать с соответствующими библиотеками / объектными файлами или скомпилировать файлы реализации
- Объявленная и неопределенная переменная или функция.
- Общие проблемы с элементами класса
- Реализации шаблонов не отображаются.
- Символы были определены в программе на языке C и использовались в коде C ++.
- Неправильно импортировать / экспортировать методы / классы по модулям / dll. (Спецификация MSVS)
- Зависимость круговой библиотеки
- неопределенная ссылка на `WinMain @ 16 '
- Порядок взаимозависимых библиотек
- Несколько исходных файлов с таким же именем
- Мистификация или отсутствие включения расширение .lib при использовании
#pragma
(Microsoft Visual Studio)- Проблемы с друзьями шаблонов
- Несогласован
UNICODE
определения
Код:
List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);
Примечание: Определенно, накладные расходы памяти.
Если вы не хотите дубликатов, используйте Установить вместо List
. Чтобы преобразовать List
в Set
, вы можете использовать следующий код:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
Если действительно необходимо, вы можете использовать ту же конструкцию, чтобы преобразовать Set
обратно в List
.
Можно удалить дубликаты из arraylist без использования HashSet или еще одного arraylist.
Попробуйте этот код ..
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
Выход:
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
В Java 8:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
Обратите внимание, что контракт hashCode-equals для членов списка должен соблюдаться для правильной работы фильтрации.
Если вы хотите использовать стороннюю библиотеку, вы можете использовать метод distinct()
в Eclipse Collections (ранее GS Collections).
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
Преимущество использования distinct()
вместо преобразования в набор, а затем обратно в список состоит в том, что distinct()
сохраняет порядок исходного списка, сохраняя первое вхождение каждого элемента.
MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;
Если вы не можете преобразовать исходный список в тип коллекций Eclipse, вы можете использовать ListAdapter для получения того же API.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Примечание: я являюсь коммиттером для коллекций Eclipse.
for(int a=0;a<myArray.size();a++){
for(int b=a+1;b<myArray.size();b++){
if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
myArray.remove(b);
dups++;
b--;
}
}
}
Вот мой код без использования какой-либо другой структуры данных, такой как set или hashmap
for(int i = 0; i < Models.size(); i++) {
for(int j = i + 1; j < Models.size(); j++) {
if(Models.get(i).getName().equals(Models.get(j).getName())){
Models.remove(j);
j--;
}
}
}
вы можете использовать вложенный цикл:
ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();
Iterator iterator1 = l1.iterator();
boolean repeated = false;
while (iterator1.hasNext())
{
Class1 c1 = (Class1) iterator1.next();
for (Class1 _c: l2) {
if(_c.getId() == c1.getId())
repeated = true;
}
if(!repeated)
l2.add(c1);
}
Вот способ, который не влияет на упорядочение списка:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext())
{
YourClass o = (YourClass) iterator.next();
if(!l2.contains(o)) l2.add(o);
}
l1 является исходным списком, а l2 - списком без повторных элементов (убедитесь, что у YourClass есть метод equals, соответствующий тому, что вы хотите стоять за равенство)
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");
HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
Хотя преобразование ArrayList
в HashSet
эффективно удаляет дубликаты, если вам нужно сохранить порядок вставки, я предпочел бы вам использовать этот вариант
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Тогда, если вы необходимо вернуть ссылку List
, вы можете снова использовать конструктор преобразования.
Потоки Java 8 обеспечивают очень простой способ удаления повторяющихся элементов из списка. Используя отличный метод. Если у нас есть список городов, и мы хотим удалить дубликаты из этого списка, это можно сделать в одной строке -
List<String> cityList = new ArrayList<>();
cityList.add("Delhi");
cityList.add("Mumbai");
cityList.add("Bangalore");
cityList.add("Chennai");
cityList.add("Kolkata");
cityList.add("Mumbai");
cityList = cityList.stream().distinct().collect(Collectors.toList());
Предположим, что у нас есть список String
, например:
List<String> strList = new ArrayList<>(5);
// insert up to five items to list.
. Затем мы можем удалить повторяющиеся элементы несколькими способами.
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Примечание. Если мы хотим сохранить порядок вставки, нам нужно использовать LinkedHashSet
на месте из HashSet
.
Эти три строки кода могут удалить дублированный элемент из ArrayList или любой коллекции.
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}
Когда вы заполняете ArrayList, используйте условие для каждого элемента. Например:
ArrayList< Integer > al = new ArrayList< Integer >();
// fill 1
for ( int i = 0; i <= 5; i++ )
if ( !al.contains( i ) )
al.add( i );
// fill 2
for (int i = 0; i <= 10; i++ )
if ( !al.contains( i ) )
al.add( i );
for( Integer i: al )
{
System.out.print( i + " ");
}
Получим массив {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Вы также можете сделать это таким образом и сохранить порядок:
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
import java.util.*;
class RemoveDupFrmString
{
public static void main(String[] args)
{
String s="appsc";
Set<Character> unique = new LinkedHashSet<Character> ();
for(char c : s.toCharArray()) {
System.out.println(unique.add(c));
}
for(char dis:unique){
System.out.println(dis);
}
}
}
Существует также ImmutableSet
из Guava в качестве опции ( здесь - документация):
ImmutableSet.copyOf(list);
Решение @ jonathan-stafford в порядке. Но это не сохраняет порядок списка.
Если вы хотите сохранить порядок в списке, вы должны использовать это:
public static <T> void removeDuplicate(List <T> list) {
Set <T> set = new HashSet <T>();
List <T> newList = new ArrayList <T>();
for (Iterator <T>iter = list.iterator(); iter.hasNext(); ) {
Object element = iter.next();
if (set.add((T) element))
newList.add((T) element);
}
list.clear();
list.addAll(newList);
}
Это только для завершения ответа. Очень хорошо!
List<String> result = new ArrayList<String>();
Set<String> set = new LinkedHashSet<String>();
String s = "ravi is a good!boy. But ravi is very nasty fellow.";
StringTokenizer st = new StringTokenizer(s, " ,. ,!");
while (st.hasMoreTokens()) {
result.add(st.nextToken());
}
System.out.println(result);
set.addAll(result);
result.clear();
result.addAll(set);
System.out.println(result);
output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
ArrayList<String> list = new ArrayList<String>();
HashSet<String> unique = new LinkedHashSet<String>();
HashSet<String> dup = new LinkedHashSet<String>();
boolean b = false;
list.add("Hello");
list.add("Hello");
list.add("how");
list.add("are");
list.add("u");
list.add("u");
for(Iterator iterator= list.iterator();iterator.hasNext();)
{
String value = (String)iterator.next();
System.out.println(value);
if(b==unique.add(value))
dup.add(value);
else
unique.add(value);
}
System.out.println(unique);
System.out.println(dup);
Если вы хотите удалить дубликаты из ArrayList, найдите следующую логику,
public static Object[] removeDuplicate(Object[] inputArray)
{
long startTime = System.nanoTime();
int totalSize = inputArray.length;
Object[] resultArray = new Object[totalSize];
int newSize = 0;
for(int i=0; i<totalSize; i++)
{
Object value = inputArray[i];
if(value == null)
{
continue;
}
for(int j=i+1; j<totalSize; j++)
{
if(value.equals(inputArray[j]))
{
inputArray[j] = null;
}
}
resultArray[newSize++] = value;
}
long endTime = System.nanoTime()-startTime;
System.out.println("Total Time-B:"+endTime);
return resultArray;
}
LinkedHashSet выполнит трюк.
String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
System.out.println(s1);
System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
System.out.println(arr3[i].toString());
// output: 5,1,2,3,4
это может решить проблему:
private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {
Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
Наверное, немного перебор, но мне нравится такая изолированная проблема. :)
Этот код использует временную Set (для проверки уникальности), но удаляет элементы непосредственно в исходном списке. Поскольку удаление элементов внутри ArrayList может вызвать огромное количество копий массивов, метод remove (int) исключается.
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();
}
}
}
Используйте интерфейс маркера для представления единого решения для List:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
EDIT: Я думаю, что generics-stuff действительно не добавляет никаких Здесь. О, хорошо. :)