Is there something like a ObservableConcurrentLinkedDeque? - java

in my code i need a ConcurrentLinkedDeque but i want to bind this Deque biiderectional to a TableView in JavaFX or at least the size of the Deque to a PieChart, whats the common way to do something like this. Is there something like a ObservableConcurrentLinkedDeque i could use instead of the ConcurrentLinkedDeque and bind directly to a TableView?

There is no such implementation in the JavaFX library.
Note that it really doesn't make sense to implement a concurrent collection of any kind for use as a backing list for a TableView (or any other JavaFX node that is bound to its state). Once you use this as the backing data for a UI node, it can only be accessed from the JavaFX thread, so making it thread safe is redundant. So you are reduced to asking for an observable list that is also a Deque.
To do this, you could subclass ModifiableObservableListBase, delegating it to a LinkedList, and implement Deque, also delegating those methods to the LinkedList. You just need to be careful to fire changes when you call Deque methods that modify the list. So something like:
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import javafx.collections.ModifiableObservableListBase;
public class ObservableLinkedList<T> extends ModifiableObservableListBase<T> implements Deque<T> {
private final LinkedList<T> list = new LinkedList<>();
#Override
public void addFirst(T e) {
list.addFirst(e);
beginChange();
nextAdd(0, 1);
++modCount ;
endChange();
}
#Override
public void addLast(T e) {
list.addLast(e);
int size = list.size();
beginChange();
nextAdd(size-1, size);
++modCount ;
endChange();
}
#Override
public boolean offerFirst(T e) {
addFirst(e);
return true ;
}
#Override
public boolean offerLast(T e) {
addLast(e);
return true ;
}
#Override
public T removeFirst() {
T old = list.removeFirst() ;
beginChange();
nextRemove(0, old);
++modCount ;
endChange();
return old ;
}
#Override
public T removeLast() {
T old = list.removeLast() ;
beginChange();
nextRemove(list.size(), old);
++modCount ;
endChange();
return old ;
}
#Override
public T pollFirst() {
T result = list.pollFirst();
if (result != null) {
beginChange();
nextRemove(0, result);
++modCount ;
endChange();
}
return result ;
}
#Override
public T pollLast() {
T result = list.pollLast();
if (result != null) {
beginChange();
nextRemove(list.size(), result);
++modCount ;
endChange();
}
return result ;
}
#Override
public T getFirst() {
return list.getFirst() ;
}
#Override
public T getLast() {
return list.getLast() ;
}
#Override
public T peekFirst() {
return list.peekFirst() ;
}
#Override
public T peekLast() {
return list.peekLast() ;
}
#Override
public boolean removeFirstOccurrence(Object o) {
// not efficient: maybe a more efficient way, but we need the index...
int index = list.indexOf(o);
if (index > -1) {
remove(index);
return true ;
} else {
return false ;
}
}
#Override
public boolean removeLastOccurrence(Object o) {
// not efficient: maybe a more efficient way, but we need the index...
int index = list.lastIndexOf(o);
if (index > -1) {
remove(index);
return true ;
} else {
return false ;
}
}
#Override
public boolean offer(T e) {
return offerLast(e);
}
#Override
public T remove() {
return removeFirst();
}
#Override
public T poll() {
return pollFirst();
}
#Override
public T element() {
return getFirst();
}
#Override
public T peek() {
return peekFirst();
}
#Override
public void push(T e) {
addFirst(e);
}
#Override
public T pop() {
return removeFirst();
}
#Override
public Iterator<T> descendingIterator() {
return list.descendingIterator();
}
#Override
public T get(int index) {
return list.get(index);
}
#Override
public int size() {
return list.size();
}
#Override
protected void doAdd(int index, T element) {
list.add(index, element);
}
#Override
protected T doSet(int index, T element) {
return list.set(index, element);
}
#Override
protected T doRemove(int index) {
return list.remove(index);
}
}
Usage example:
ObservableLinkedList<String> list = new ObservableLinkedList<>();
list.addListener((Change<? extends String> c) -> {
while (c.next()) {
if (c.wasAdded()) {
System.out.println("Added from "+c.getFrom()+" to "+c.getTo()+" "+c.getAddedSubList());
}
if (c.wasRemoved()) {
System.out.println("Removed from "+c.getFrom() + " to "+c.getTo()+" "+c.getRemoved());
}
if (c.wasUpdated()) {
System.out.println("Updated");
}
if (c.wasPermutated()) {
System.out.println("Permutated");
}
}
});
list.addAll("Two", "Three", "Four");
list.offerFirst("One");
list.offer("Five");
System.out.println(list.pollFirst());
System.out.println(list.pollLast());

Related

Search filter using rxjava1 android(java)

I have a list and i got search filter. I have done using EditText listeners and using for loop. But i want the filter should handle by rxjava
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
Log.i(TAG, "Search text: " + charSequence);
List<AllAttendance> list = new ArrayList<>();
//filter from all List
if (rbtnAll.isChecked())
list = filter(mAttendanceList, charSequence);
else if (rbtnPending.isChecked())
list = filter(mPendingAttendanceList, charSequence);
setAdapterData(list);
rvAttendance.scrollToPosition(0);
}
private List<AllAttendance> filter(List<AllAttendance> mAttendanceList, CharSequence charSequence) {
String text = String.valueOf(charSequence);
text = text.toLowerCase();
List<AllAttendance> filteredList = new ArrayList<>();
for (AllAttendance attendance : mAttendanceList){
if (attendance.getMandalName().toLowerCase().contains(text) || attendance.getSabhaName().toLowerCase().contains(text) || attendance.getSabhaDate().toLowerCase().contains(text))
filteredList.add(attendance);
}
return filteredList;
}
Here is a piece of code i have used for searching with AndroidRx.
NOTE : In this example i am making a network call on every character change after waiting for 1000 ms.
PublishSubject<String> subject = PublishSubject.create();
subject.debounce(1000, TimeUnit.MILLISECONDS)
.filter(new Predicate<String>() {
#Override
public boolean test(#NonNull String s) throws Exception {
return s.length() > 0;
}
})
.switchMap(new Function<String, Observable<SearchViewResponseModel>>() {
#Override
public Observable<SearchViewResponseModel> apply(#NonNull String o) throws Exception {
return api.getSearchResult(PrefsManager.getToken(SearchActivity.this), o, 0, 10);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<SearchViewResponseModel>() {
#Override
public void onNext(#NonNull SearchViewResponseModel s) {
adapter.clear();
for (SearchViewResponseModel.Data model : s.getData())
adapter.add(new SearchViewModel(model.get_id(), model.getThumbnail(), model.getTitle()));
}
#Override
public void onError(#NonNull Throwable e) {
e.printStackTrace();
}
#Override
public void onComplete() {
Log.i("Completed", "");
}
});
searchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(final String newText) {
subject.onNext(newText);
return true;
}
});
}

Java list only addition no deletion

I want to know if there is any possibility that we can create a Java java.util.List which only allows the addition of element but doesn't allow the removal of elements?
One way I am thinking of overriding remove method. Please suggest.
This could be achieved using Decorator pattern. This way it could be applied to all container that implement List:
private static class UnremovableList<E> implements List<E> {
private List<E> innerContainer;
public UnremovableList(List<E> original) {
innerContainer = original
}
#Override
public void add(int location, E object) {
innerContainer.add(location, object);
}
#Override
public boolean add(E object) {
return innerContainer.add(object);
}
#Override
public boolean addAll(int location, Collection<? extends E> collection) {
return innerContainer.addAll(location, collection);
}
#Override
public boolean addAll(Collection<? extends E> collection) {
return innerContainer.addAll(collection);
} -
#Override
public void clear() {
throw new UnsupportedOperationException();
}
#Override
public boolean contains(Object object) {
return innerContainer.contains(object);
}
#Override
public boolean containsAll(Collection<?> collection) {
return innerContainer.containsAll(collection);
}
#Override
public E get(int location) {
return innerContainer.get(location);
}
#Override
public int indexOf(Object object) {
return innerContainer.indexOf(object);
}
#Override
public boolean isEmpty() {
return innerContainer.isEmpty();
}
#NonNull
#Override
public ListIterator<E> listIterator() {
return listIterator(0);
}
#NonNull
#Override
public Iterator<E> iterator() {
return new Iterator<E>() {
Iterator<E> iterator = innerContainer.iterator();
#Override public boolean hasNext() {
return iterator.hasNext();
}
#Override public E next() {
return iterator.next();
}
#Override public void remove() {
throw new UnsupportedOperationException();
}
};
}
#Override
public ListIterator<E> listIterator(final int location) {
return new ListIterator<E>() {
ListIterator<E> iterator = innerContainer.listIterator(location);
#Override public void add(E object) {
throw new UnsupportedOperationException();
}
#Override public boolean hasNext() {
return iterator.hasNext();
}
#Override public boolean hasPrevious() {
return iterator.hasPrevious();
}
#Override public E next() {
return iterator.next();
}
#Override public int nextIndex() {
return iterator.nextIndex();
}
#Override public E previous() {
return iterator.previous();
}
#Override public int previousIndex() {
return iterator.previousIndex();
}
#Override public void remove() {
throw new UnsupportedOperationException();
}
#Override public void set(E object) {
throw new UnsupportedOperationException();
}
};
}
#Override
public int lastIndexOf(Object object) {
return innerContainer.lastIndexOf(object);
}
#Override
public E remove(int location) {
throw new UnsupportedOperationException();
}
#Override
public boolean remove(Object object) {
throw new UnsupportedOperationException();
}
#Override
public boolean removeAll(Collection<?> collection) {
throw new UnsupportedOperationException();
}
#Override
public boolean retainAll(Collection<?> collection) {
throw new UnsupportedOperationException();
}
#Override
public E set(int location, E object) {
return innerContainer.set(location, object);
}
#Override
public int size() {
return innerContainer.size();
}
#NonNull
#Override
public List<E> subList(int start, int end) {
return new UnremovableList(innerContainer.subList(start, end));
}
#NonNull
#Override
public Object[] toArray() {
return innerContainer.toArray();
}
#NonNull
#Override
public <T> T[] toArray(T[] array) {
return innerContainer.toArray(array);
}
}
Usage:
List<String> stableList = new UnremovableList(Arrays.asList("A", "B", "C"));
You can extend an existing List implementing class and override all public deleting methods, but it are quite a few methods to override (maybe even more, below are all I've found quickly)
public class UnDeletableList<E> extends ArrayList<E> {
#Override
public E remove(int index) {
throw new UnsupportedOperationException("don't remove from this list");
}
#Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("don't remove from this list");
}
#Override
public boolean removeAll(Collection<?> o) {
throw new UnsupportedOperationException("don't remove from this list");
}
#Override
public boolean retainAll(Collection<?> o) {
throw new UnsupportedOperationException("don't remove from this list");
}
#Override
public void clear() {
throw new UnsupportedOperationException("don't remove from this list");
}
// OPTIONAL IN CASE OF EXTRA STRICTNESS
#Override
public void replaceAll(UnaryOperator<E> u) {
throw new UnsupportedOperationException("don't remove from this list");
}
#Override
public E set(int i, E e) {
throw new UnsupportedOperationException("don't remove from this list");
}
}

How to sort ArrayList while implementing Parcelable

I am trying to sort the category arraylist with Collections.sort method but have no luck with it.
Here is my code:
public class Categories implements Parcelable {
private ArrayList<Category> category;
private Recent recent;
public ArrayList<Category> getCategories() {
return this.category;
}
public void setCategory(ArrayList<Category> category) {
this.category = category;
}
public Recent getRecent() {
return this.recent;
}
public void setRecent(Recent recent) {
this.recent = recent;
}
protected Categories(Parcel in) {
if (in.readByte() == 0x01) {
category = new ArrayList<Category>();
in.readList(category, Category.class.getClassLoader());
} else {
category = null;
}
recent = (Recent) in.readValue(Recent.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
if (category == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(category);
}
dest.writeValue(recent);
}
public static final Parcelable.Creator<Categories> CREATOR = new Parcelable.Creator<Categories>() {
#Override
public Categories createFromParcel(Parcel in) {
return new Categories(in);
}
#Override
public Categories[] newArray(int size) {
return new Categories[size];
}
};
}
You can also use custom comparator:
public class CategoriesComparator implements Comparator<Category> {
#Override
public int compare(Category category1, Category category2) {
return category1.getSomeProperty().compareTo(category2.getSomeProperty());
}
}
When you want to compare call this:
Collections.sort(yourListCategories, new CategoriesComparator());
Hope it helps!
Collections.sort(yourListHere,new Comparator<Categories>() {
#Override
public int compare(Categories lhs, Categories rhs) {
//your sort logic here
return 0;
}
});
Hope this helps.

How to add certain paths in the List?

Code below counts files with certain name. TypeCount is then some number (four for example).
File dir = new File(Environment.getExternalStorageDirectory().toString(), "/AppDir/" );
File[] files=dir.listFiles();
int typeCount = 0;
String type = "dog";
for (int i=0; i<files.length; i++) {
File file = files[i];
String filepath = file.getPath();
if(filepath.contains(type)){
typeCount = typeCount + 1;
}
}
In this code I want to put every path (File) in the List<File>. But when I set typeCount to size of the List I get always zero instead.
File dir = new File(Environment.getExternalStorageDirectory().toString(), "/AppDir/" );
File dir = new File(Environment.getExternalStorageDirectory().toString(), "/AppDir/" );
File[] files=dir.listFiles();
int typeCount = 0;
String typeype = "dog";
List<File> myList;
myList = new List<File>() {
#Override
public void add(int i, File file) {
}
#Override
public boolean add(File file) {
return false;
}
#Override
public boolean addAll(int i, Collection<? extends File> collection) {
return false;
}
#Override
public boolean addAll(Collection<? extends File> collection) {
return false;
}
#Override
public void clear() {
}
#Override
public boolean contains(Object o) {
return false;
}
#Override
public boolean containsAll(Collection<?> collection) {
return false;
}
#Override
public File get(int i) {
return null;
}
#Override
public int indexOf(Object o) {
return 0;
}
#Override
public boolean isEmpty() {
return false;
}
#NonNull
#Override
public Iterator<File> iterator() {
return null;
}
#Override
public int lastIndexOf(Object o) {
return 0;
}
#Override
public ListIterator<File> listIterator() {
return null;
}
#NonNull
#Override
public ListIterator<File> listIterator(int i) {
return null;
}
#Override
public File remove(int i) {
return null;
}
#Override
public boolean remove(Object o) {
return false;
}
#Override
public boolean removeAll(Collection<?> collection) {
return false;
}
#Override
public boolean retainAll(Collection<?> collection) {
return false;
}
#Override
public File set(int i, File file) {
return null;
}
#Override
public int size() {
return 0;
}
#NonNull
#Override
public List<File> subList(int i, int i1) {
return null;
}
#NonNull
#Override
public Object[] toArray() {
return new Object[0];
}
#NonNull
#Override
public <T> T[] toArray(T[] ts) {
return null;
}
};
for (int i=0; i<files.length; i++){
File file = files[i];
String filepath = file.getPath();
if(filepath.contains(type)){
myList.add(file);
}
}
typeCount = myList.size();
What is wrong here?
(And a little off topic - Is path written correctly? I'm not sure about it.)
This method size() will always print 0 because your own List implementation has a wrong returning statement:
#Override
public int size() {
return 0; // Oops!
}
Another thing too, you don't really insert anything in your List because of this:
#Override
public boolean add(File file) {
return false; // Hum...
}
Your methods aren't completed yet to execute the same tasks as a normal List. You better should use ArrayList<File> or List<File> which will have all the right methods and won't require hard work from you. Don't reinvent the wheel ;)
Finally, the path are right declared, but you should test if the files are presents in the folder before executing the code. Something as follows:
File[] files = dir.listFiles();
if (files.length > 0) {
// loop and add to a list
}

Implement a TransformList that holds distinct values?

I'm trying to create an implementation of TransformList that maintains a list of distinct values off a source list. However, I'm a little puzzled on how the implementation should add the distinct values to my hashmap and distinct list that are contained internally. I think my ListChangeListener.change should work though. But how do I intercept any new or removed distinct values and add/remove them to the distinct map and list?
public class DistinctList<E> extends TransformationList<E,E> {
private final ObservableList<E> distinctList = FXCollections.observableArrayList();
private final ConcurrentHashMap<E,E> distinctValues = new ConcurrentHashMap<>();
private final ObservableList<E> source;
public DistinctList(ObservableList<E> source) {
super(source);
this.source = source;
source.stream().filter(s -> attemptAdd(s)).forEach(s -> distinctList.add(s));
}
private boolean attemptAdd(E e) {
final boolean result = distinctValues.putIfAbsent(e,e) == null;
if (result) {
distinctList.add(e);
}
return result;
}
private boolean attemptRemove(E e) {
final boolean result = distinctValues.remove(e, e);
if (result) {
distinctList.remove(e);
}
return result;
}
#Override
protected void sourceChanged(ListChangeListener.Change<? extends E> c) {
fireChange(new ListChangeListener.Change<E>(this) {
#Override
public boolean wasAdded() {
if (c.getAddedSubList().stream().filter(v -> distinctValues.contains(v) == false).findAny().isPresent()) {
return true;
}
else {
return false;
}
}
#Override
public boolean wasRemoved() {
if (c.getRemoved().stream().filter(v -> !source.contains(v)).findAny().isPresent()) {
return true;
}
else {
return false;
}
}
#Override
public boolean wasPermutated() {
return false;
}
#Override
protected int[] getPermutation() {
throw new AssertionError("getPermutation() not implemented");
}
#Override
public List<E> getRemoved() {
return c.getRemoved().stream().filter(v -> !source.contains(v)).collect(Collectors.toList());
}
#Override
public int getFrom() {
return 0;
}
#Override
public int getTo() {
return 0;
}
#Override
public boolean next() {
return c.next();
}
#Override
public void reset() {
c.reset();
}
});
}
#Override
public int getSourceIndex(int index) {
return IntStream.range(0,source.size()).filter(i -> source.get(i).equals(this.get(i))).findAny().orElse(-1);
}
#Override
public E get(int index) {
return distinctList.get(index);
}
#Override
public int size() {
return distinctList.size();
}
}
UPDATE
I kept working with this and I think I figured out where to interact source changes with the distinct value map and list. But when my source list removes a value (and other values with same hashcode/equals still exists), it wrongly removes the value from the distinct values. What am I doing wrong?
public class DistinctList<E> extends TransformationList<E,E> {
private final ObservableList<E> distinctList = FXCollections.observableArrayList();
private final ConcurrentHashMap<E,E> distinctValues = new ConcurrentHashMap<>();
private final ObservableList<E> source;
public DistinctList(ObservableList<E> source) {
super(source);
this.source = source;
source.stream().forEach(s -> attemptAdd(s));
}
private boolean attemptAdd(E e) {
final boolean result = distinctValues.putIfAbsent(e,e) == null;
if (result) {
distinctList.add(e);
}
return result;
}
private boolean attemptRemove(E e) {
final boolean result = distinctValues.remove(e, e);
if (result) {
distinctList.remove(e);
}
return result;
}
#Override
protected void sourceChanged(ListChangeListener.Change<? extends E> c) {
ListChangeListener.Change<E> change = new ListChangeListener.Change<E>(this) {
#Override
public boolean wasAdded() {
if (c.getAddedSubList().stream().filter(v -> source.contains(v)).findAny().isPresent()) {
return true;
}
else {
return false;
}
}
#Override
public boolean wasRemoved() {
if (c.getRemoved().stream().filter(v -> source.contains(v) == false).findAny().isPresent()) {
return true;
}
else {
return false;
}
}
#Override
public boolean wasPermutated() {
return false;
}
#Override
protected int[] getPermutation() {
throw new AssertionError("getPermutation() not implemented");
}
#Override
public List<E> getRemoved() {
return c.getRemoved().stream().filter(v -> source.contains(v) == false)
.collect(Collectors.toList());
}
#Override
public int getFrom() {
return 0;
}
#Override
public int getTo() {
return 0;
}
#Override
public boolean next() {
return c.next();
}
#Override
public void reset() {
c.reset();
}
};
while (c.next()) {
if (c.wasAdded()) {
c.getAddedSubList().stream().filter(v -> !distinctValues.containsKey(v)).peek(a -> System.out.println("ADDING FROM MAP " + a)).forEach(a -> attemptAdd(a));
}
if (c.wasRemoved()) {
c.getRemoved().stream().filter(v -> distinctValues.containsKey(v)).peek(a -> System.out.println("REMOVING FROM MAP " + a)).forEach(a -> attemptRemove(a));
}
}
fireChange(change);
}
#Override
public int getSourceIndex(int index) {
return IntStream.range(0,source.size()).filter(i -> source.get(i).equals(this.get(i))).findAny().orElse(-1);
}
#Override
public E get(int index) {
return distinctList.get(index);
}
#Override
public int size() {
return distinctList.size();
}
}
I think I got it. Let me know if I'm missing anything.
public class DistinctList<E> extends TransformationList<E,E> {
private final ObservableList<E> distinctList = FXCollections.observableArrayList();
private final ConcurrentHashMap<E,E> distinctValues = new ConcurrentHashMap<>();
private final ObservableList<E> source;
public DistinctList(ObservableList<E> source) {
super(source);
this.source = source;
source.stream().forEach(s -> attemptAdd(s));
}
private boolean attemptAdd(E e) {
final boolean result = distinctValues.putIfAbsent(e,e) == null;
if (result) {
distinctList.add(e);
}
return result;
}
private boolean attemptRemove(E e) {
final boolean result = distinctValues.remove(e, e);
if (result) {
distinctList.remove(e);
}
return result;
}
#Override
protected void sourceChanged(ListChangeListener.Change<? extends E> c) {
while (c.next()) {
ListChangeListener.Change<E> change = new ListChangeListener.Change<E>(this) {
#Override
public boolean wasAdded() {
if (c.getAddedSubList().stream().filter(v -> distinctValues.contains(v) == false).findAny().isPresent()) {
return true;
} else {
return false;
}
}
#Override
public List<E> getAddedSubList() {
return c.getAddedSubList().stream().filter(v -> distinctValues.contains(v) == false).collect(Collectors.toList());
}
#Override
public boolean wasRemoved() {
if (c.getRemoved().stream().filter(v -> source.contains(v) == false).findAny().isPresent()) {
return true;
} else {
return false;
}
}
#Override
public boolean wasPermutated() {
return false;
}
#Override
protected int[] getPermutation() {
throw new AssertionError("getPermutation() not implemented");
}
#Override
public List<E> getRemoved() {
return c.getRemoved().stream().filter(v -> source.contains(v) == false)
.collect(Collectors.toList());
}
#Override
public int getFrom() {
return 0;
}
#Override
public int getTo() {
return 0;
}
#Override
public boolean next() {
return c.next();
}
#Override
public void reset() {
c.reset();
}
};
if (change.wasAdded()) {
change.getAddedSubList().stream().filter(v -> !distinctValues.containsKey(v)).peek(a -> System.out.println("ADDING FROM MAP " + a)).forEach(a -> attemptAdd(a));
}
if (change.wasRemoved()) {
change.getRemoved().stream().filter(v -> distinctValues.containsKey(v)).peek(a -> System.out.println("REMOVING FROM MAP " + a)).forEach(a -> attemptRemove(a));
}
fireChange(change);
}
}
#Override
public int getSourceIndex(int index) {
return IntStream.range(0,source.size()).filter(i -> source.get(i).equals(this.get(i))).findAny().orElse(-1);
}
#Override
public E get(int index) {
return distinctList.get(index);
}
#Override
public int size() {
return distinctList.size();
}
}

Categories