/** * Returns a set view of the keys contained in this map. */ @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") // Safe because immutable. public final Set<K> keySet() { if (keySet == null) { keySet = DerivedSet.create(storage.keySet(), keyConverter); } return keySet; }
/** * Returns {@code true} if this set contains no elements. * * @return {@code true} if this set contains no elements. */ @Override public boolean isEmpty() { return !storage.isEmpty() || !iterator().hasNext(); }
/** * Creates a new derived set from the specified storage set. * * @param storage the set which actually store the elements. * @param converter the converter from the type in the storage set to the type in the derived set. */ static <S,E> Set<E> create(final Set<S> storage, final ObjectConverter<S,E> converter) { final Set<FunctionProperty> properties = converter.properties(); if (properties.contains(FunctionProperty.INVERTIBLE)) { if (FunctionProperty.isBijective(properties)) { return new Bijective<>(storage, converter); } return new Invertible<>(storage, converter); } return new DerivedSet<>(storage, converter); }
/** * Ensures that this set contains the specified element. * This method first checks if the given element is non-null, * then delegates to the {@link #storage} set like below: * * {@preformat java * return storage.add(inverse.apply(element)); * } * * @param element element whose presence in this set is to be ensured. * @return {@code true} if the set changed as a result of the call. * @throws UnsupportedOperationException if the {@linkplain #storage} set doesn't * supports the {@code add} operation. */ @Override public boolean add(final E element) throws UnsupportedOperationException { return add(element, converter.inverse().apply(element)); }
/** * Creates a new derived set from the specified storage set. * * @param storage the set which actually store the elements. * @param converter the converter from the type in the storage set to the type in the derived set. */ static <S,E> Set<E> create(final Set<S> storage, final ObjectConverter<S,E> converter) { final Set<FunctionProperty> properties = converter.properties(); if (properties.contains(FunctionProperty.INVERTIBLE)) { if (FunctionProperty.isBijective(properties)) { return new Bijective<>(storage, converter); } return new Invertible<>(storage, converter); } return new DerivedSet<>(storage, converter); }
/** * Ensures that this set contains the specified element. * This method first checks if the given element is non-null, * then delegates to the {@link #storage} set like below: * * {@preformat java * return storage.add(inverse.apply(element)); * } * * @param element element whose presence in this set is to be ensured. * @return {@code true} if the set changed as a result of the call. * @throws UnsupportedOperationException if the {@linkplain #storage} set doesn't * supports the {@code add} operation. */ @Override public boolean add(final E element) throws UnsupportedOperationException { return add(element, converter.inverse().apply(element)); }
/** * Returns a set view of the keys contained in this map. * * @return a view of the keys in this map. */ @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") public final Set<K> keySet() { if (keySet == null) { keySet = DerivedSet.create(storage.keySet(), keyConverter); } return keySet; }
/** * Returns {@code true} if this set contains no elements. * * @return {@code true} if this set contains no elements. */ @Override public boolean isEmpty() { return storage.isEmpty() || !iterator().hasNext(); }
/** * Returns a set view of the mappings contained in this map. */ @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") // Safe because immutable. public final Set<Map.Entry<K,V>> entrySet() { if (entrySet == null) { entrySet = DerivedSet.create(storage.entrySet(), this); } return entrySet; }
/** * Returns a set view of the mappings contained in this map. * * @return a view of the entries in this map. */ @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") public final Set<Map.Entry<K,V>> entrySet() { if (entrySet == null) { entrySet = DerivedSet.create(storage.entrySet(), this); } return entrySet; }
return null; return DerivedSet.create(storage, converter);
return null; return DerivedSet.create(storage, converter);
/** * Tests {@link DerivedSet} with an excluded value. */ @Test public void testWithExclusion() { final Set<Integer> source = new HashSet<>(Arrays.asList(2, 7, 12, EXCLUDED, 20)); final Set<Integer> target = new HashSet<>(Arrays.asList(20, 70, 120, 200)); final Set<Integer> tested = DerivedSet.create(source, this); assertEquals(target.size(), tested.size()); assertEquals(target, tested); assertFalse(tested.contains(EXCLUDED * 10)); }
/** * Tests {@link DerivedSet} without excluded value. */ @Test public void testNoExclusion() { final Set<Integer> source = new HashSet<>(Arrays.asList(2, 7, 12, 17, 20 )); final Set<Integer> target = new HashSet<>(Arrays.asList(20, 70, 120, 170, 200)); final Set<Integer> tested = DerivedSet.create(source, this); assertEquals(target.size(), tested.size()); assertEquals(target, tested); assertFalse("contains(2)", tested.contains(2 )); // Original value assertTrue ("contains(20)", tested.contains(20)); // Derived value assertTrue ("before remove(70)", source.contains(7 )); assertTrue ( "remove(70)", tested.remove (70)); assertFalse( "after remove(70)", source.contains(7 )); assertTrue ( "remove(70)", target.remove (70)); // For comparison purpose. assertEquals(target, tested); assertFalse("before add(30)", source.contains(3 )); assertTrue ( "add(30)", tested.add (30)); assertTrue ( "after add(30)", source.contains(3 )); assertTrue ( "add(30)", target.add (30)); // For comparison purpose. assertEquals(target, tested); }