有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java实现了一个包含不同值的TransformList?

我试图创建TransformList的一个实现,它维护一个源列表之外的不同值列表。然而,对于实现应该如何将不同的值添加到我的hashmap和内部包含的不同列表中,我有点困惑。不过我觉得我的ListChangeListener.change应该行得通。但是我如何截取任何新的或删除的不同值,并将它们添加/删除到不同的映射和列表中呢

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();
    }
}

共 (1) 个答案

  1. # 1 楼答案

    我想我明白了。如果我遗漏了什么,请告诉我

    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();
        }
    }