Implemented QueuedLinkedList
This commit is contained in:
parent
52039e9804
commit
2e1b50c96c
@ -0,0 +1,109 @@
|
||||
package ru.dragonestia.picker.service.impl.collection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class QueuedLinkedList<ITEM extends QueuedLinkedList.Item> {
|
||||
|
||||
private Node<ITEM> first;
|
||||
private Node<ITEM> last;
|
||||
private Node<ITEM> cursor;
|
||||
private final Map<String, Node<ITEM>> itemMap = new HashMap<>();
|
||||
|
||||
public void add(ITEM item) {
|
||||
if (itemMap.containsKey(item.getId())) return;
|
||||
|
||||
Node<ITEM> node = new Node<>(item);
|
||||
if (first == null) {
|
||||
first = node;
|
||||
last = first;
|
||||
} else {
|
||||
node.prev = last;
|
||||
last.next = node;
|
||||
last = node;
|
||||
}
|
||||
|
||||
itemMap.put(item.getId(), node);
|
||||
}
|
||||
|
||||
public void remove(ITEM item) {
|
||||
if (!itemMap.containsKey(item.getId())) return;
|
||||
|
||||
var node = itemMap.get(item.getId());
|
||||
itemMap.remove(item.getId());
|
||||
node.removed = true;
|
||||
|
||||
if (node.prev == null) { // first element
|
||||
first = node.next;
|
||||
if (first != null) {
|
||||
first.prev = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.next == null) { // last element
|
||||
last = node.prev;
|
||||
if (last != null) {
|
||||
last.next = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.next != null && node.prev != null) { // middle element
|
||||
var prev = node.prev;
|
||||
var next = node.next;
|
||||
|
||||
prev.next = next;
|
||||
next.prev = prev;
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return itemMap.size();
|
||||
}
|
||||
|
||||
public void resetCursor() {
|
||||
cursor = null;
|
||||
}
|
||||
|
||||
public ITEM pick() {
|
||||
if (first == null) {
|
||||
throw new RuntimeException("List is empty");
|
||||
}
|
||||
|
||||
if (cursor == null) cursor = first;
|
||||
|
||||
Node<ITEM> item = cursor;
|
||||
while (item != null && item.removed) {
|
||||
item = item.next;
|
||||
}
|
||||
if (item == null) item = first;
|
||||
|
||||
cursor = item.next;
|
||||
return item.object;
|
||||
}
|
||||
|
||||
private static class Node<ITEM extends Item> {
|
||||
|
||||
private final ITEM object;
|
||||
private Node<ITEM> prev, next;
|
||||
private boolean removed = false;
|
||||
|
||||
public Node(ITEM object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{Node id=%s, prev=%s, next=%s, removed=%s }".formatted(
|
||||
object.getId(),
|
||||
prev == null? null : prev.object.getId(),
|
||||
next == null? null : next.object.getId(),
|
||||
removed
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public interface Item {
|
||||
|
||||
String getId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package ru.dragonestia.picker.collection;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import ru.dragonestia.picker.service.impl.collection.QueuedLinkedList;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class QueuedLinkedListTests {
|
||||
|
||||
@Test
|
||||
void testQueuedLinkedList() {
|
||||
var list = new QueuedLinkedList<Item>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
list.add(new Item(Integer.toString(i)));
|
||||
}
|
||||
|
||||
printList(list);
|
||||
|
||||
var removed = new HashSet<String>();
|
||||
for (int i = 5; i < 8; i++) {
|
||||
var id = Integer.toString(i);
|
||||
|
||||
list.remove(new Item(id));
|
||||
System.out.println("Removed: " + id);
|
||||
removed.add(id);
|
||||
}
|
||||
|
||||
printList(list);
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
var item = list.pick();
|
||||
|
||||
System.out.println("Picked: " + item.getId());
|
||||
Assertions.assertFalse(removed.contains(item.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private void printList(QueuedLinkedList<Item> list) {
|
||||
list.resetCursor();
|
||||
|
||||
var sb = new StringBuilder("List(" + list.size() + "): ");
|
||||
for (int i = 0, n = list.size(); i < n; i++) {
|
||||
sb.append(i);
|
||||
if (i + 1 != n) sb.append(", ");
|
||||
}
|
||||
System.out.println(sb);
|
||||
}
|
||||
|
||||
public static class Item implements QueuedLinkedList.Item {
|
||||
|
||||
private final String id;
|
||||
|
||||
public Item(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user