实现一个包含不同值的 TransformList?
Implement a TransformList that holds distinct values?
我正在尝试创建一个 TransformList 的实现,它在源列表之外维护一个不同值的列表。但是,我对实现应该如何将不同的值添加到我的哈希图和内部包含的不同列表感到有点困惑。我认为我的 ListChangeListener.change
应该可以。但是我如何拦截任何新的或删除的不同值并将它们 add/remove 到不同的映射和列表中?
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();
}
}
更新
我一直在努力解决这个问题,我想我想出了在何处与不同的值映射和列表交互源更改。但是,当我的源列表删除一个值(并且具有相同 hashcode/equals 的其他值仍然存在)时,它错误地从不同的值中删除了该值。我做错了什么?
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();
}
}
我想我明白了。如果我遗漏了什么,请告诉我。
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();
}
}
我正在尝试创建一个 TransformList 的实现,它在源列表之外维护一个不同值的列表。但是,我对实现应该如何将不同的值添加到我的哈希图和内部包含的不同列表感到有点困惑。我认为我的 ListChangeListener.change
应该可以。但是我如何拦截任何新的或删除的不同值并将它们 add/remove 到不同的映射和列表中?
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();
}
}
更新
我一直在努力解决这个问题,我想我想出了在何处与不同的值映射和列表交互源更改。但是,当我的源列表删除一个值(并且具有相同 hashcode/equals 的其他值仍然存在)时,它错误地从不同的值中删除了该值。我做错了什么?
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();
}
}
我想我明白了。如果我遗漏了什么,请告诉我。
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();
}
}