Here I come, there I am.

 

Има няколко интуитивни начина да ни хрумне да премахнем елементи от List. Списъкът може да бъде числов, от стрингове, обекти и др. Можем да опитаме да премахнем елементите в него, като обходим масива с foreach, да обходим с for от 0 до края на колекцията или директно да боравим с итератор.

На първо време имаме една колекция, която ще манипулираме.

List<Integer> list = new ArrayList<Integer>();
		for (int index = 0; index < 50; index++) {
			list.add(index);
		}
 

Колекцията има стойности от 0 до 49 включително, като искаме да се отървем от нечетните такива. Да опитаме да направим бързо обхождане с foreach и да премахнем елементите, които не функционират:

		for (Integer element : list) {
			if (element % 2 == 1) {
				list.remove(list.indexOf(element));
			}
		}
 
 

Получаваме java.util.ConcurrentModificationException, тъй като не можем да манипулираме колекция по време на итерация с foreach поради скрит достъп до итератора на списъка. Друг проблем е поддръжката на foreach едва от Java 5.0 насам.

Втори опит - цикълче от 0 до размера на списъка.

		int length = list.size();
		for (int index = 0; index < length; index++) {
			if (list.get(index) % 2 == 1) {
				list.remove(index);
			}
		}
 
 

По някое време гръмваме, тъй като махаме елементи по време на итерация, което променя размерността на масива. Не викам list.size() всеки път, докато итерирам, защото не е добра практика да преизчислявам една и съща функция постоянно (кофти от гледна точка на бързодействие). Ако все пак подменя променливата (с дължината на колекцията) и на нейно място изчислявам всеки път дължината, то тя ще се преизчислява преди всяка итерация и примерът ще работи.

Сигурно решение, ако мажем по колекцията, докато я обхождаме, е работата с итератор.

		Iterator<Integer> iterator = list.iterator();
		while (iterator.hasNext()) {
			int step = iterator.next();
			if (step % 2 == 1) {
				iterator.remove();
			}
		}
 
 

При желание използваме remove() метода на итератора, който премахва елемента и прескача на следващия елемент до излизане в null на динамичната памет.

Всички методчета:

package sorting;
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
public class ListManipulator {
	public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
		for (int index = 0; index < 50; index++) {
			list.add(index);
		}
		// removeWithIndex(list);
		// removeForeach(list);
		 removeIterator(list);
 
		System.out.println(list);
	}
 
	private static void removeIterator(List<Integer> list) {
		Iterator<Integer> iterator = list.iterator();
		while (iterator.hasNext()) {
			int step = iterator.next();
			if (step % 2 == 1) {
				iterator.remove();
			}
		}
	}
 
	private static void removeForeach(List<Integer> list) {
		for (Integer element : list) {
			if (element % 2 == 1) {
				list.remove(list.indexOf(element));
			}
		}
 
	}
 
	private static void removeWithIndex(List<Integer> list) {
		int length = list.size();
		// performance non-wise workaround
		// for(int index = 0; index < list.size(); index++) {
		for (int index = 0; index < length; index++) {
			if (list.get(index) % 2 == 1) {
				list.remove(index);
			}
		}
	}
}
 
 

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • MySpace
  • Slashdot
  • Technorati
  • TwitThis
del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com

Безподобния пост.

Related posts brought to you by Yet Another Related Posts Plugin.

Comments

Leave a Reply