How do you compare a copy of the class with the collection containing it?



  • I have different objects I keep in different collections.

    How do we proceed with a method that would add this copy to the collection that contains these objects? Let's say all these classes are Car, Plane, Train inherited from the general parent of Transport.

    Is there any point in creating a map that would bring the class into line with a collection containing copies of this class?

    Collection<Car> cars = new HashSet<>();
    Collection<Plane> planes = new HashSet<>();
    Collection<Train> trains = new HashSet<>();
    

    Map<Transport,Collection<Transport>> bondMap;

    public void add(Transport transport) {
    // тут по классу аргумента добавление в соответствующую коллекцию
    }



  • I don't think there's a good simple solution, but you can invent something.

    Inspired. https://books.google.ru/books?id=ka2VUBqHiWkC&lpg=PA142&ots=yZGnPnt0TX&hl=ru&pg=PA142#v=onepage&q&f=false from Joshua Bloch - Effective Java:

    class TypeCollections<T> {
        private Map<Class<? extends T>, Collection<? extends T>> map = new HashMap<>();
    
    public &lt;E extends T&gt; void putCollection( Class&lt;E&gt; clazz, Collection&lt;E&gt; collection ) {
        Objects.requireNonNull( clazz, "argument 'clazz' must be non-null" );
        Objects.requireNonNull( collection, "argument 'collection' must be non-null" );
        map.put( clazz, collection );
    }
    
    public &lt;E extends T&gt; void addValue( E value ) {
        Objects.requireNonNull( value, "Null value not accepted" );
    
        @SuppressWarnings("unchecked")
        // здесь игнорируются предупреждения компилятора о небезопасном
        //   приведении типа, но т.к. мы знаем, что для
        //   типа E у нас лежит или Collection&lt;E&gt; или ничего, 
        //   то просим компилятор заткнуться.
        Collection&lt;E&gt; collection = (Collection&lt;E&gt;)map.get( value.getClass() );
        if ( collection != null ) {
            collection.add( value );
        }
    }
    

    }

    Use:

    class Transport{};

    class Car extends Transport {};
    class Plane extends Transport {};
    class Train extends Transport {};

    class Spaceship extends Transport {};

    public class TypeSafety {
    HashSet<Car> cars = new HashSet<>();
    Set<Plane> planes = new HashSet<>();
    Collection<Train> trains = new HashSet<>();

    // будет принимать только классы, наследующие Transport
    TypeCollections&lt;Transport&gt; tsc = new TypeCollections&lt;Transport&gt;();
    {   
        tsc.putCollection( Car.class, cars );
        // поскольку Set&lt;Plane&gt; наследует Collection&lt;Plane&gt;, можно
        //   добавить один из подклассов Collection, если совпадает тип параметра
        tsc.putCollection( Plane.class, planes );
        tsc.putCollection( Train.class, trains );
    }
    
    public void add( Transport transport ) {
        tsc.addValue( transport );
    }
    
    public void printCollections() {
        System.out.println( cars.toString() );
        System.out.println( planes.toString() );
        System.out.println( trains.toString() );
    }
    
    public static void main( String[] args ) {
        TypeSafety test = new TypeSafety();
    
        List&lt;Transport&gt; transports = Arrays.asList( 
                new Train(),
                new Car(),
                new Plane(), new Plane(),
                new Train(),
                new Plane(),
                new Car(), new Car(),
                new Spaceship()
            );
    
        for( Transport t : transports ) {
            test.add( t );
        }
    
        test.printCollections();
        // Вывод:
        //   [sandbox.Car@7852e922, sandbox.Car@3d4eac69, sandbox.Car@55f96302]
        //   [sandbox.Plane@33909752, sandbox.Plane@70dea4e, sandbox.Plane@4e25154f]
        //   [sandbox.Train@5c647e05, sandbox.Train@6d06d69c]
        //
        // Spaceship мимо пролетел. 
    }
    

    }

    This decision has many shortcomings:

    • Can't be used for classrooms. For example:

      TypeCollections<Comparable<String>> t = new TypeCollections<>();
      {
      t.putCollection( Comparable<String>.class, new ArrayList<Comparable<String>>());
      }

      not compromised, i.e. use Comparable<String>.class Not as the type parameter information is erased at the time of implementation and references to different versions Comparable I'd like to see one. Bloch refers to technology http://gafter.blogspot.ru/2006/12/super-type-tokens.html (the reference in the commentaries is an example of implementation for collections).

    • Heirs are ignored. For example, if you add a class class SportCar extends Car {}; to code:

      test.add( new SportCar() );

    Not adding this object to the collection. cars Examples above.


Log in to reply
 


Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2