Это мой код. Поддержка IE [6-9], chrome 17 +, firefox, Opera 11 +, Maxthon3
HTML
<input type="file" id="netBarBig" onchange="changeFile(this)" />
<img src="" id="imagePreview" style="width:120px;height:80px;" alt=""/>
javascript:
<script>
function previewImage(fileObj, imgPreviewId) {
var allowExtention = ".jpg,.bmp,.gif,.png"; //allowed to upload file type
document.getElementById("hfAllowPicSuffix").value;
var extention = fileObj.value.substring(fileObj.value.lastIndexOf(".") + 1).toLowerCase();
var browserVersion = window.navigator.userAgent.toUpperCase();
if (allowExtention.indexOf(extention) > -1) {
if (fileObj.files) {
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById(imgPreviewId).setAttribute("src", e.target.result);
};
reader.readAsDataURL(fileObj.files[0]);
} else if (browserVersion.indexOf("SAFARI") > -1) {
alert("don't support Safari6.0 below broswer");
}
} else if (browserVersion.indexOf("MSIE") > -1) {
if (browserVersion.indexOf("MSIE 6") > -1) {//ie6
document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
} else {//ie[7-9]
fileObj.select();
fileObj.blur();
var newPreview = document.getElementById(imgPreviewId);
newPreview.style.border = "solid 1px #eeeeee";
newPreview.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + document.selection.createRange().text + "')";
newPreview.style.display = "block";
}
} else if (browserVersion.indexOf("FIREFOX") > -1) {//firefox
var firefoxVersion = parseFloat(browserVersion.toLowerCase().match(/firefox\/([\d.]+)/)[1]);
if (firefoxVersion < 7) {//firefox7 below
document.getElementById(imgPreviewId).setAttribute("src", fileObj.files[0].getAsDataURL());
} else {//firefox7.0+
document.getElementById(imgPreviewId).setAttribute("src", window.URL.createObjectURL(fileObj.files[0]));
}
} else {
document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
}
} else {
alert("only support" + allowExtention + "suffix");
fileObj.value = ""; //clear Selected file
if (browserVersion.indexOf("MSIE") > -1) {
fileObj.select();
document.selection.clear();
}
}
}
function changeFile(elem) {
//file object , preview img tag id
previewImage(elem,'imagePreview')
}
</script>
Iterator.remove()
безопасно, можно использовать его как это:
List<String> list = new ArrayList<>();
// This is a clever way to create the iterator and call iterator.hasNext() like
// you would do in a while-loop. It would be the same as doing:
// Iterator<String> iterator = list.iterator();
// while (iterator.hasNext()) {
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
// Remove the current element from the iterator and the list.
iterator.remove();
}
}
Примечание, что Iterator.remove()
единственный безопасный способ изменить набор во время повторения; поведение является неуказанным, если базовый набор изменяется каким-либо другим способом , в то время как повторение происходит.
Источник: docs.oracle> Интерфейс Набора
<час> И точно так же если Вы имеете ListIterator
и хотите к [1 112], добавляет объекты, можно использовать ListIterator#add
по той же причине, которую можно использовать Iterator#remove
— это разработано для разрешения его.
В Вашем случае Вы пытались удалить из списка, но то же ограничение применяется при попытке к put
в Map
при итерации его содержания.
Это работает:
Iterator<Integer> iter = l.iterator();
while (iter.hasNext()) {
if (iter.next() == 5) {
iter.remove();
}
}
я предположил, что, так как цикл foreach является синтаксическим сахаром для итерации, использование итератора не помогло бы..., но это дает Вам этот .remove()
функциональность.
Можно или использовать итератор непосредственно как Вы упомянутый, или иначе сохранить второй набор и добавить каждый объект, который Вы хотите удалить к новому набору, тогда removeAll в конце. Это позволяет Вам продолжать использовать безопасность типов цикла foreach за счет увеличенного использования памяти, и процессорное время (не должна быть огромная проблема, если Вы не имеете действительно, действительно большие списки или действительно старый компьютер)
public static void main(String[] args)
{
Collection<Integer> l = new ArrayList<Integer>();
Collection<Integer> itemsToRemove = new ArrayList<Integer>();
for (int i=0; i < 10; ++i) {
l.add(new Integer(4));
l.add(new Integer(5));
l.add(new Integer(6));
}
for (Integer i : l)
{
if (i.intValue() == 5)
itemsToRemove.add(i);
}
l.removeAll(itemsToRemove);
System.out.println(l);
}
Одно решение могло состоять в том, чтобы повернуть список и удалить первый элемент для ухода от ConcurrentModificationException или IndexOutOfBoundsException
int n = list.size();
for(int j=0;j<n;j++){
//you can also put a condition before remove
list.remove(0);
Collections.rotate(list, 1);
}
Collections.rotate(list, -1);
Поскольку на вопрос уже дан ответ, т.е. лучший способ - использовать метод удаления объекта-итератора, я бы подробно остановился на том месте, где возникает ошибка "java. util.ConcurrentModificationException "
.
Каждый класс коллекции имеет частный класс, который реализует интерфейс Iterator и предоставляет такие методы, как next ()
, remove ()
и hasNext ()
.
Код для next выглядит примерно так ...
public E next() {
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch(IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
Здесь метод checkForComodification
реализован как
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Итак, как вы можете видеть, если вы явно попытаетесь удалить элемент из коллекция. Это приводит к тому, что modCount
отличается от expectedModCount
, что приводит к исключению ConcurrentModificationException
.