2016-02-12 2 views
2

Как удалить элементы списка из списка, как показано нижеКак удалить элементы в списке на основе класса ПСД значения

List<Mypojaclass> results = new ArrayList<>(); 
     // in the results i am adding more items using sql query, after that, 
     if(Mypojaclass sensor : results){ 
      if(sensor.getType.equals("JD"){ 
      sensor.remove(sensor); 
      } 
     } 

Я могу сделать это с помощью итератора, если его, как показано ниже,

List<String> results = new ArrayList<>(); 
for (Iterator<String> iter = list.listIterator(); iter.hasNext();) { 
    String a = iter.next(); 
    if (...) { 
     iter.remove(); 
    } 
} 

Но Я должен удалить элементы только на основе этого sensor.getType.

Как я могу достичь этого?

+0

Замечание по качеству кода: ваш фрагмент кода подразумевает, что у вас есть функция, которая должна собирать список объектов в виде списка результатов. И затем ваш метод начинает вносить изменения в другую структуру данных? Если это так: не делайте этого (если ваш метод на самом деле не похож на collectFooAndUpdateBar или что-то подобное). Я говорю: собирать что-то и обновлять что-то еще ... это то, что не принадлежит одному месту. – GhostCat

+1

@MMMMS Вы хотите удалить все случаи, когда getType равно «JD» или только первое вхождение? –

+0

У вашего вопроса есть ответ. Используя Iterator, вы можете получить POJO и удалить его, если тип равен JD. – Samurai

ответ

5

Использование Java 8 вы можете сделать это:

results = results.stream().filter(p ->! p.getType().equals("JD")).collect(Collectors.toList()); 

Для Java 7 и ниже безопасной ставки будет:

Iterator<Mypojaclass> itr = results.iterator(); 
while(itr.hasNext()){ 
    Mypojaclass item = itr.next(); 
    if("JD".equals(item.getType())){ 
     itr.remove(); 
    } 
} 
+0

Ваш пример Java 8 фильтрует список в обратном порядке, он содержит только элементы с getType == JD –

+0

@Seelenvirtuose это было бы лучше? results.stream(). filter (p ->! p.getType(). equals ("JD")). collect (Collectors.toCollection (ArrayList :: new)); –

+0

cf 'Эффективная Java, 2nd Edition, Chapter 5, Item 23: Не использовать необработанные типы в новом коде' –

-1

Просто используйте для цикла:

List<Mypojaclass> results = new ArrayList<>(); 
// in the results i am adding more items using sql query, after that, 
for(int i = 0; i < results.size(); i++) { 
    if(results.get(i).getType.equals("JD"){ 
     results.remove(i); 
    } 
} 

Или просто используйте Iterator напрямую:

List<Mypojaclass> results = new ArrayList<>(); 
// in the results i am adding more items using sql query, after that, 
Iterator<Mypojaclass> iterator = results.iterator() 
while(iterator.hasNext()) { 
    if(iterator.next().getType().equals("JD"){ 
     iterator.remove(); 
    } 
} 
2

Для Java 8:

results.removeIf(f -> f.getType().equals("JD")); 

Удаляет все элементы из списка, имеющих тип "JD"

Для простого Java 7:

List<Mypojaclass> filteredResults = new ArrayList<>(); 
for (Mypojaclass item: results) { 
    if (!item.getType().equals("JD")) { 
     filteredResults.add(item); 
    } 
} 

Alternative

Iterator<Mypojaclass> iterator = results.iterator(); 
while (iterator.hasNext()) { 
    Mypojaclass item = iterator.next(); 
    if (item.getType().equals("JD")) { 
     iterator.remove(); 
    } 
}  

Теперь фильтруется Результаты содержат отфильтрованный список. В случае Java 7 вы также можете подумать об использовании коллекций коллекций, которые содержат методы для достижения этого механизма фильтрации.

results.stream().filter(p -> p.getType().equals("JD")); 

Из приведенного выше комментария ничего не делается. Вам нужно будет собрать элементы в новом списке, и вам придется отказаться от предиката фильтра, потому что иначе вы получите коллекцию с просто элементами, которые имеют тип «JD»

+1

Я бы добавил, что даже лучше проверить, что '' JD ".equals (f.getType())' для предотвращения NPE. В качестве альтернативы вы можете использовать 'Objects.equals (f.getType()," JD ")'! Конечно, это полностью зависит от вашего контекста, и если вы делаете чек в «безопасной зоне» –

+0

@LouisF. Это не полностью предотвратило бы NPE. 'f' также может быть« null ». – Seelenvirtuose

+0

@Seelenvirtuose хороший улов! –

0

Я знаю, что это не опрятная, но я думаю, что это работает

List<Mypojaclass> results = new ArrayList<Mypojaclass>(); 
Mypojaclass [] placeHolder = null; //this will hold the object(s) to be removed 
int length = 0;      //this will hold the length of this new array of placeHolder array 
for (Mypojaclass sensor : results) { 
    if(sensor.getType.equals("JD"){ 
    length++; 
    } 
} 

placeHolder = new Mypojaclass[length]; //allocates memory 

for (Mypojaclass sensor : results){ 
    if(sensor.getType.equals("JD"){ 
    placeHolder[length-1] = sensor;  //initialize 
    length--; 
    } 
} 

//This will remove all instances when getType equals "JD" 
for(int i = 0; i < placeHolder.length; i++){ 
    results.remove(placeHolder[i]); 
}  
+0

Это удалит только последний экземпляр с типом 'JD'. – bradimus

+0

'placeholder' переназначается каждый раз, когда цикл встречает элемент с типом' 'JD" '. Последний такой столкновение будет удален. Если вы хотите удалить первый, вам нужно «разбить» цикл. – bradimus

+0

Хотя это кажется технически правильным (не оценил его), я бы не рекомендовал этот подход. Создание временного массива совершенно не нужно. – Seelenvirtuose

3

я решил дать ответ, потому что другие, похоже, бороться со списками, итераторы, ручьи, и так далее.

Во-первых, проблема:

Фрагмент кода, как этот

List<Mypojaclass> results = ...; 
for (Mypojaclass sensor : results) { 
    if (sensor.getType.equals("JD") { 
     results.remove(sensor); // <-- possible CME here 
    } 
} 

глючит, потому что он может просто бросить ConcurrentModificationException.Причина заключается в том, что для-каждой петли используется итератор, поэтому приведенный выше код эквивалентен следующему коду, который использует явный итератор:

List<Mypojaclass> results = ...; 
for (Iterator<Mypojaclass> itr = result.iterator(); itr.hasNext();) { 
    Mypojaclass sensor = itr.next(); 
    if (sensor.getType.equals("JD") { 
     results.remove(sensor); 
    } 
} 

Обратите внимание, что вы называете remove в списке, а не на итератор. Итератор затем бросает CME, потому что список был изменен за пределами итератора.

Решение:

Вызовите remove операцию на итератора:

List<Mypojaclass> results = ...; 
for (Iterator<Mypojaclass> itr = result.iterator(); itr.hasNext();) { 
    Mypojaclass sensor = itr.next(); 
    if (sensor.getType.equals("JD") { 
     itr.remove(); 
    } 
} 

Теперь этот фрагмент кода перебирает раз через весь список, одновременно удаляя все вхождения датчиков типа которых равна " JD».

Java 8 Код:

Как мы теперь в времени AERA Java 8, это будет делать то же самое в Java 8:

results.removeIf(s -> s.getType().equals("JD")); 

Или - с помощью потока и некоторые фильтры:

List<Mypojaclass> filtered = results 
     .stream() 
     .filter(s -> !s.getType().equals("JD")) 
     .collect(Collectors.toList()); 
results = filtered; 

Обратите внимание, что предикат фильтра должен быть отменен. Вы не хотите иметь типы «JD». Вы хотите иметь все остальные типы.

+0

Спасибо. хорошее объяснение – MMMMS

Смежные вопросы