Ranides Atterwim vor 10 Jahren
Ursprung
Commit
743bd9777e
1 geänderte Dateien mit 291 neuen und 0 gelöschten Zeilen
  1. 291 0
      assira/src/main/java/net/ranides/assira/collection/lists/JoinList.java

+ 291 - 0
assira/src/main/java/net/ranides/assira/collection/lists/JoinList.java

@@ -0,0 +1,291 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.lists;
+
+import java.util.*;
+
+/**
+ * Klasa reprezentująca złączenie wielu list jako jedną kolekcję.
+ * @param <T>
+ * @author ranides
+ * @todo (migration) assira
+ */
+public class JoinList<T> extends AbstractSequentialList<T> {
+
+    private final List<List<T>> content;
+
+    public JoinList() {
+        content = new LinkedList<>();
+    }
+    
+    public JoinList(List<T>... values) {
+        this();
+        joinAll(Arrays.asList(values));
+    }
+    
+    public JoinList(List<List<T>> values) {
+        this();
+        joinAll(values);
+    }
+    
+    /**
+     * Dodaje do kolekcji kolejną listę. Uwaga: dodawana jest <b>lista</b>, a nie
+     * jej elementy.
+     * @param list
+     * @return this
+     */
+    public JoinList<T> join(List<T> list) {
+        content.add(list);
+        return this;
+    }
+    
+    /**
+     * Dodaje do kolekcji kolejną listę. Uwaga: dodawana jest <b>lista</b>, a nie
+     * jej elementy.
+     * @param list
+     * @return this
+     */
+    public JoinList<T> join(int index, List<T> list) {
+        content.add(index, list);
+        return this;
+    }
+    
+    /***
+     * Dodaje do kolekcji kolejne listy. Uwaga: dodawane są <b>listy</b>, a nie
+     * ich elementy.
+     * @param list
+     * @return 
+     */
+    public final JoinList<T> joinAll(List<List<T>> list) {
+        content.addAll(list);
+        return this;
+    }
+    
+    /**
+     * Dodaje do kolekcji kolejne listy. Uwaga: dodawane są <b>listy</b>, a nie
+     * ich elementy.
+     * @param list
+     * @return this
+     */
+    public final JoinList<T> joinAll(int index, List<List<T>> list) {
+        content.addAll(index, list);
+        return this;
+    }
+
+    @Override
+    public int size() {
+        int size = 0;
+        for(List<T> list : content) {
+            size += list.size();
+        }
+        return size;
+    }
+
+    @Override
+    public boolean contains(Object value) {
+        for(List<T> list : content) {
+            if( list.contains(value) ) { return true; }
+        }
+        return false;
+    }
+
+    @Override
+    public T get(int index) {
+        int begin, end = 0;
+        for(List<T> list : content) {
+            begin = end;
+            end += list.size();
+            if(index < end) {
+                return list.get(index - begin);
+            }
+        }
+        throw new IndexOutOfBoundsException("index=" + index + " size=" + end );
+    }
+    
+    @Override
+    public void add(int index, T element) {
+        int begin, end = 0;
+        for(List<T> list : content) {
+            begin = end;
+            end += list.size();
+            if(index < end) {
+                list.add(index - begin, element);
+                return;
+            }
+        }
+        throw new IndexOutOfBoundsException("index=" + index + " size=" + end );
+    }
+
+    @Override
+    public boolean addAll(int index, Collection<? extends T> values) {
+        int begin, end = 0;
+        for(List<T> list : content) {
+            begin = end;
+            end += list.size();
+            if(index < end) {
+                return list.addAll(index - begin, values);
+            }
+        }
+        throw new IndexOutOfBoundsException("index=" + index + " size=" + end );
+    }
+
+    @Override
+    public T remove(int index) {
+        int begin, end = 0;
+        for(List<T> list : content) {
+            begin = end;
+            end += list.size();
+            if(index < end) {
+                return list.remove(index - begin);
+            }
+        }
+        throw new IndexOutOfBoundsException("index=" + index + " size=" + end );
+    }
+
+    
+
+    @Override
+    public T set(int index, T element) {
+        int begin, end = 0;
+        for(List<T> list : content) {
+            begin = end;
+            end += list.size();
+            if(index < end) {
+                return list.set(index - begin, element);
+            }
+        }
+        throw new IndexOutOfBoundsException("index=" + index + " size=" + end );
+    }
+
+    @Override
+    public ListIterator<T> listIterator(int index) {
+        return new JoinIterator(content, index);
+    }
+    
+    private static final class JoinIterator<T> implements ListIterator<T> {
+        
+        private ListIterator<List<T>> li;
+        private ListIterator<T> ci;
+        private int csize;
+        private int begin;
+
+        public JoinIterator(List<List<T>> data, int index) {
+            li = data.listIterator();
+            csize = 0;
+            ci = null;
+            
+            if(index == 0) {
+                return;
+            }
+            
+            while(li.hasNext()) {
+                begin += csize;
+                index -= begin;
+                
+                List<T> list = li.next();
+                csize = list.size();
+                
+                if(index < begin) {
+                    ci = list.listIterator(index - begin);
+                    return;
+                }
+            }
+            
+            throw new IndexOutOfBoundsException("index=" + index);
+        }
+
+        @Override
+        public boolean hasNext() {
+            if(ci!=null && ci.hasNext()) {
+                return true;
+            }
+            while(li.hasNext()) {
+                begin += csize;
+                List<T> list = li.next();
+                csize = list.size();
+                if(csize>0) {
+                    ci = list.listIterator();
+                    return true;
+                }
+            }
+            ci = null;
+            return false;
+        }
+
+        @Override
+        public T next() {
+            if(!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            return ci.next();
+        }
+
+        @Override
+        public int nextIndex() {
+            return ci!=null ? begin + ci.nextIndex() : 0;
+        }
+
+        @Override
+        public boolean hasPrevious() {
+            if(ci!=null && ci.hasPrevious()) {
+                return true;
+            }
+            while(li.hasPrevious()) {
+                begin -= csize;
+                List<T> list = li.previous();
+                csize = list.size();
+                if(csize > 0) {
+                    ci = list.listIterator();
+                    return true;
+                }
+            }
+            ci = null;
+            return false;
+        }
+
+        @Override
+        public T previous() {
+            if(!hasPrevious()) {
+                throw new NoSuchElementException();
+            }
+            return ci.previous();
+        }
+
+        @Override
+        public int previousIndex() {
+            return ci!=null ? begin + ci.previousIndex() : -1;
+        }
+
+        @Override
+        public void remove() {
+            if(ci==null) {
+                throw new IllegalStateException();
+            }
+            ci.remove();
+            csize--;
+        }
+
+        @Override
+        public void set(T e) {
+            if(ci==null) {
+                throw new IllegalStateException();
+            }
+            ci.set(e);
+        }
+
+        @Override
+        public void add(T e) {
+            if(ci==null && !hasNext()) {
+                throw new IllegalStateException("JoinList must contain at least one list if you want to add elements");
+            }
+            ci.add(e);
+            csize++;
+        }
+        
+    }
+    
+}