5

Tôi muốn sử dụng danh sách được liên kết để thực hiện trích xuất và chèn các yếu tố, thử tất cả các kết hợp cho một phỏng đoán. Danh sách được liên kết hiệu quả hơn đối với loại hoạt động này. Vì tôi muốn thử tất cả các cặp trích xuất/chèn có thể, tôi đã sử dụng hai trình lặp khác nhau trong danh sách. Điều này làm tăng "ConcurrentModificationException". Làm thế nào tôi có thể thực hiện hoạt động này một cách hiệu quả, mà không phải duyệt lại danh sách mỗi lần, vì điều này sẽ đánh bại toàn bộ mục đích của việc sử dụng danh sách ở nơi đầu tiên?Làm thế nào để sử dụng hai trình lặp khác nhau trên một Danh sách Liên kết trong Java?

Dưới đây là phần có liên quan của mã:

ListIterator<Integer> it1 = data.listIterator(); 
ListIterator<Integer> it2; 

while(it1.hasNext()) { 
    int i = it1.next(); 
    it2 = data.listIterator(); 

    while(it2.hasNext()) { 
     if (i == it2.next()) continue; // continue right away when the indexes are equal 
     it1.remove(); 
     it2.add(i); 
     if (length() < best) 
      return true; 
     } 

    // when the swap is not better/consistent 
    it2.remove(); 
    it1.add(i); 
} 
return false; 

Cảm ơn

+2

Nếu bạn thay đổi danh sách thông qua một trình lặp, bạn không thể sử dụng bất kỳ trình lặp nào khác. –

+1

Bạn có thể sử dụng ConcurrentLinkedQueue thay vì không nhận được CME không? Tôi nghi ngờ có cách hiệu quả hơn để làm bất cứ điều gì bạn đang làm trong mọi trường hợp. –

+0

Vui lòng google như vậy: www.google.com/search?q=multi+dimensional+linked+list+java và kiểm tra kết quả như http://www.dreamincode.net/forums/topic/282327-multi-dimensional-linked -list/ –

Trả lời

0

Bạn có thể sử dụng bất kỳ số lặp trên DANH khi bạn đang làm chỉ là một hoạt động đọc. Vì bạn đang thực hiện xóa/thêm ở đây, bạn không thể sử dụng cùng danh sách với hai trình lặp khác nhau vì nó sẽ gây ra ConcurrentModificationException như bạn đang gặp phải bây giờ.

Bạn muốn đạt được điều gì? Có thể, mọi người có thể giúp bạn với các tùy chọn khác nhau.

+1

Bạn không nên viết nhận xét làm câu trả lời. –

+0

Đồng ý. Nhưng không cho phép tôi thêm bình luận vì tình trạng khởi động trong stackoverflow: ( – muruga

+0

Như hai giờ trước, điều đó không còn đúng nữa :) Ngưỡng là 50. –

1

Bạn không thể sử dụng nhiều biến lặp đồng thời trên một LinkedList, tuy nhiên bạn có thể với một CopyOnWriteArrayList

Hãy thử điều này:

List<Integer> safeData = new CopyOnWriteArrayList(date); 
// your code, but working with safeData rather than data 
+0

Cảm ơn bạn, nhưng điều này được thực hiện như một mảng, không phải là danh sách. Điều này có nghĩa là chèn sẽ không hiệu quả; O (n) thay vì O (1). –

+1

@DavidBlinder chèn sẽ kém hiệu quả hơn, nhưng không phải vì bất cứ điều gì bạn đã nói. danh sách * sử dụng * mảng nội bộ, nhưng lớp đặc biệt này tạo toàn bộ bản sao của chính nó trong nội bộ về thay đổi để làm cho nó trở thành chủ đề an toàn - xem javadoc được liên kết – Bohemian

1

Nếu tôi giúp bạn đúng, bạn tìm kiếm một cấu trúc dữ liệu mà cung cấp một số trình vòng lặp để thao tác danh sách. Đây là khó khăn về mặt kỹ thuật đối với java.util.LinkedList ban đầu vì nó thực hiện việc dọn dẹp chỉ mục hiện tại và điều này chỉ có thể có hiệu quả nếu không có sự thay đổi song song ở các vị trí không xác định trong danh sách bởi các trình vòng lặp khác. Tuy nhiên, bạn có thể dễ dàng thực hiện một LinkedList đơn giản không thực hiện việc dọn dẹp này và hỗ trợ thêm/xóa thông qua một số trình lặp. Sau đó, một iterator không biết vị trí của nó trong danh sách, nhưng tôi đặt cược bạn không quan tâm. Chỉ cần sử dụng một cái gì đó như thế này:

public class MyList<T> { 
private MyNode<T> first = null, last = null; 

public MyNode<T> getFirst() { 
    return first; 
} 

public MyNode<T> getLast() { 
    return last; 
} 

public boolean contains(MyNode<T> n) { 
    return n.list == this; 
} 

/** 
* If beforeMe is null, toInsert is inserted at the end of the list. 
* @return inserted node 
*/ 
public void insertBefore(MyNode<T> beforeMe, MyNode<T> newNode) { 
    if (newNode == null) { 
     throw new IllegalArgumentException("toInsert must not be null!"); 
    } 

    if (newNode.list != null) { 
     throw new IllegalArgumentException("This node is already in the list " + newNode.list); 
    } 

    if (beforeMe == null) { 
     if (last == null) { 
      newNode.prev = newNode.next = null; 
      first = last = newNode; 
     } else { 
      last.next = newNode; 
      newNode.prev = last; 
      newNode.next = null; 
      last = newNode; 
     } 
    } else { 
     newNode.prev = beforeMe.prev; 
     newNode.next = beforeMe; 

     if (beforeMe.prev != null) { 
      beforeMe.prev.next = newNode; 
     } else { 
      first = newNode; 
     } 

     beforeMe.prev = newNode; 
    } 

    newNode.list = this; 
} 

/** 
* If beforeMe is null, t is inserted at the end of the list. 
* @return inserted node 
*/ 
public MyNode<T> insertBefore(MyNode<T> beforeMe, T t) { 
    MyNode<T> newNode = new MyNode<T>(t); 
    insertBefore(beforeMe, newNode); 
    return newNode; 
} 

public void remove(MyNode<T> n) { 
    if (n == null || n.list != this) { 
     throw new IllegalArgumentException("Node is not in the list!"); 
    } 

    if (n.prev != null) { 
     n.prev.next = n.next; 
    } else { 
     first = n.next; 
    } 

    if (n.next != null) { 
     n.next.prev = n.prev; 
    } else { 
     last = n.prev; 
    } 

    n.prev = n.next = null; 
    n.list = null; 
}} 

public class MyNode<T> { 

private T t; 
/** 
* written only by MyList 
*/ 
MyNode<T> prev = null; 
/** 
* written only by MyList 
*/ 
MyNode<T> next = null; 
/** 
* written only by MyList 
*/ 
MyList<T> list = null; 

public T get() { 
    return t; 
} 

public void set(T t) { 
    this.t = t; 
} 

public MyNode<T> previous() { 
    return prev; 
} 

public MyNode<T> next() { 
    return next; 
} 

public MyList<T> list() { 
    return list; 
} 

/** 
* called only by MyList. 
* @param t 
*/ 
MyNode(T t) { 
    this.t = t; 
}} 
Các vấn đề liên quan