Created
March 5, 2018 14:45
-
-
Save Anrimian/bcf7b7e1b56fcfdd4186e0da32dc9f99 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class DefaultInsertionPredicate<S, T> implements InsertionPredicate<S, T> { | |
| @Override | |
| public boolean canInsert(@Nonnull Section<S, T> section, @Nonnull T item) { | |
| return true; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class EntityItem<T> implements Item { | |
| private T data; | |
| public EntityItem(T data) { | |
| this.data = data; | |
| } | |
| public T getData() { | |
| return data; | |
| } | |
| @Override | |
| public boolean equals(Object o) { | |
| if (this == o) return true; | |
| if (o == null || getClass() != o.getClass()) return false; | |
| EntityItem that = (EntityItem) o; | |
| return data != null ? data.equals(that.data) : that.data == null; | |
| } | |
| @Override | |
| public int hashCode() { | |
| return data != null ? data.hashCode() : 0; | |
| } | |
| @Override | |
| public String toString() { | |
| return "EntityItem{" + | |
| "data=" + data + | |
| '}'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class HeaderItem<T> implements Item { | |
| private T title; | |
| public HeaderItem(T title) { | |
| this.title = title; | |
| } | |
| public T getTitle() { | |
| return title; | |
| } | |
| @Override | |
| public boolean equals(Object o) { | |
| if (this == o) return true; | |
| if (o == null || getClass() != o.getClass()) return false; | |
| HeaderItem that = (HeaderItem) o; | |
| return title != null ? title.equals(that.title) : that.title == null; | |
| } | |
| @Override | |
| public int hashCode() { | |
| return title != null ? title.hashCode() : 0; | |
| } | |
| @Override | |
| public String toString() { | |
| return "HeaderItem{" + | |
| "title=" + title + | |
| '}'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public interface Inserter<T> { | |
| int insert(List<T> localList, @Nonnull T item); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public interface InsertionObserver { | |
| void onInserted(@Nonnull Item item, int position); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public interface InsertionPredicate<S, T> { | |
| boolean canInsert(@Nonnull Section<S, T> section, @Nonnull T item); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public interface Item { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public interface RemoveObserver { | |
| void onRemoved(@Nonnull Item item, int position); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Section<S, T> { | |
| @Nonnull | |
| private S sectionDescription; | |
| @Nonnull | |
| private final List<Item> items; | |
| private final List<T> localItems = new ArrayList<>(); | |
| private InsertionPredicate<S, T> insertionPredicate; | |
| Section(@Nonnull S sectionDescription, | |
| @Nonnull InsertionPredicate<S, T> insertionPredicate, | |
| @Nonnull List<Item> items) { | |
| this.sectionDescription = sectionDescription; | |
| this.insertionPredicate = insertionPredicate; | |
| this.items = items; | |
| } | |
| @Nonnull | |
| public S getSectionDescription() { | |
| return sectionDescription; | |
| } | |
| @Nonnull | |
| public List<T> getLocalItems() { | |
| return localItems; | |
| } | |
| void insert(T item, | |
| int sectionOffset, | |
| Inserter<T> inserter, | |
| InsertionObserver insertionObserver) { | |
| if (localItems.isEmpty()) { | |
| HeaderItem<S> headerItem = new HeaderItem<>(sectionDescription); | |
| items.add(sectionOffset, headerItem); | |
| insertionObserver.onInserted(headerItem, sectionOffset); | |
| } | |
| int localIndex = inserter.insert(localItems, item); | |
| if (localIndex != -1) { | |
| localIndex++;//header | |
| EntityItem<T> entityItem = new EntityItem<>(item); | |
| int index = sectionOffset + localIndex; | |
| items.add(index, entityItem); | |
| insertionObserver.onInserted(entityItem, index); | |
| } | |
| } | |
| boolean canContain(T item) { | |
| return insertionPredicate.canInsert(this, item); | |
| } | |
| void remove(T item, RemoveObserver removeObserver) { | |
| EntityItem<T> entityItem = new EntityItem<>(item); | |
| int index = items.indexOf(entityItem); | |
| if (index != -1) { | |
| items.remove(index); | |
| removeObserver.onRemoved(entityItem, index); | |
| localItems.remove(item); | |
| if (localItems.isEmpty()) { | |
| index--; | |
| items.remove(index); | |
| removeObserver.onRemoved(new HeaderItem<>(sectionDescription), index); | |
| } | |
| } | |
| } | |
| @Override | |
| public String toString() { | |
| return "Section{" + | |
| "sectionDescription=" + sectionDescription + | |
| ", localItems=" + localItems + | |
| '}'; | |
| } | |
| public void clear() { | |
| localItems.clear(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Sections<S, T> { | |
| private final List<Section<S, T>> sections; | |
| private final List<Item> items; | |
| @Nullable | |
| private InsertionObserver insertionObserver; | |
| @Nullable | |
| private RemoveObserver removeObserver; | |
| Sections(List<Section<S, T>> sections, | |
| List<Item> items, | |
| @Nullable InsertionObserver insertionObserver, | |
| @Nullable RemoveObserver removeObserver) { | |
| this.sections = sections; | |
| this.items = items; | |
| this.insertionObserver = insertionObserver; | |
| this.removeObserver = removeObserver; | |
| } | |
| public void addItem(T item) { | |
| addItem(item, new SimpleInserter<>()); | |
| } | |
| public void addItem(T item, Inserter<T> inserter) { | |
| for (int i = 0; i < sections.size(); i++) { | |
| Section<S, T> section = sections.get(i); | |
| if (section.canContain(item)) { | |
| int sectionOffset = 0; | |
| if (i > 0) { | |
| Section<S, T> previousSection = sections.get(i - 1); | |
| List<T> localItems = previousSection.getLocalItems(); | |
| if (!localItems.isEmpty()) { | |
| T lastItem = localItems.get(localItems.size() - 1); | |
| sectionOffset = items.indexOf(new EntityItem<>(lastItem)) + 1; | |
| } | |
| } | |
| section.insert(item, sectionOffset, inserter, insertionObserver); | |
| break; | |
| } | |
| } | |
| } | |
| public void remove(T item) { | |
| for (Section<S, T> section: sections) { | |
| if (section.canContain(item)) { | |
| section.remove(item, removeObserver); | |
| } | |
| } | |
| } | |
| public void clear() { | |
| items.clear(); | |
| for (Section section: sections) { | |
| section.clear(); | |
| } | |
| } | |
| public List<Item> getItems() { | |
| return items; | |
| } | |
| public static class Builder<S, T> { | |
| private final List<Item> items = new ArrayList<>(); | |
| private final List<Section<S, T>> sections = new ArrayList<>(); | |
| @Nullable | |
| private InsertionObserver insertionObserver; | |
| @Nullable | |
| private RemoveObserver removeObserver; | |
| public Builder<S, T> onInsert(InsertionObserver insertionObserver) { | |
| this.insertionObserver = insertionObserver; | |
| return this; | |
| } | |
| public Builder<S, T> onRemove(RemoveObserver removeObserver) { | |
| this.removeObserver = removeObserver; | |
| return this; | |
| } | |
| public Builder<S, T> section(@Nonnull S sectionDescription, | |
| @Nonnull InsertionPredicate<S, T> insertionPredicate) { | |
| sections.add(new Section<>(sectionDescription, insertionPredicate, items)); | |
| return this; | |
| } | |
| public Builder<S, T> section(@Nonnull S sectionDescription) { | |
| return section(sectionDescription, new DefaultInsertionPredicate<>()); | |
| } | |
| public Sections<S, T> build() { | |
| return new Sections<>(sections, items, insertionObserver, removeObserver); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class SimpleInserter<T> implements Inserter<T> { | |
| @Override | |
| public int insert(List<T> localList, @Nonnull T item) { | |
| localList.add(item); | |
| return localList.size() - 1; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment