0

This question has been edited from its original version

Hi everyone, following your comments, I have modified my original class. The objective of this class is to store two sets of values:

  • The first one is the "applied" one. If the user request the data from the class, he will receive this one.
  • The second one is the "pending" changes. If the user modify the data, it will be stored into this set.
  • When the user apply the changes, they are copied in the first set.

Now, here is the class as I changed it:

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class ChangesQueue< K, V, T extends Map< K, V > > implements Serializable {

    private static final long serialVersionUID = 1L;

    HashMap< K, V > mCurrent;
    HashMap< K, V > mStack;

    public ChangesQueue() {
        mCurrent = new HashMap< K, V >();
        mStack   = new HashMap< K, V >();
    }

    public ChangesQueue(T iValue) {
        this();
        set(iValue);
        apply();
    }

    public void apply() {
        mCurrent = new HashMap< K, V >(mStack);
    }

    public Map< K, V > get() {
        return mCurrent;
    }

    public void set(T iValue) {
        mStack.putAll(iValue);
    }

}

The biggest issue that I have here is that I cannot actually store the real type of T, which is why I am instantiating 'HashMap'. But this class is not intended to work only with 'HashMap', but with any kind of maps.

Actually, I am using this memory with the following class:

public class IndexedHashMap<K, T> implements Map<K, Pair< Integer, T >>, Serializable

And accessing the data with the following method:

private IndexedHashMap<String, T> getElements()
{
    return (null != mElements.get()) ? (IndexedHashMap<String, T>) mElements.get() : new  IndexedHashMap<String, T>();
}

Of course this is not possible as the cast is not valid.

I am currently considering a simple extension of 'IndexedHashMap' but I would really need a sort of generic Memory (this is not a YAGNI case) and I do not want to get multiples, specific classes, for the same thing.

Would there be any way to do this while keeping the generic side ? Maybe it is achievable if I use a 'Class clazz' argument which would allow me to instantiate the real type of T instead of an HashMap ?

Thanks for the help

Milan
  • 1,547
  • 1
  • 24
  • 47
  • When is `mStack` ever changed? You reassign it in the `set` method, but that doesn't affect `mCurrent`. – zsmb13 Mar 03 '17 at 19:41
  • You can't copy an arbitrary object. Java doesn't provide any way to do that. You can copy the contents of a map, if you know it's a map. But currently your type `T` is unbounded. – khelwood Mar 03 '17 at 19:41
  • Can `T` be any type or can you be sure that it's always a `Map`? – QBrute Mar 03 '17 at 19:42
  • T could be any type, but for the purpose of simplicity, i could make SURE it implement Map by constraining it. however, I'd be interesting in a generic way of doing it. – Milan Mar 03 '17 at 19:47
  • The question then is how to perform initial instanciation, because I cannot instanciante 'Map' and I need a non null value to use 'Map.putAll(Map< K, V> );' – Milan Mar 03 '17 at 19:54
  • In response to your edit: the main takeaway from the duplicate is that there is no out of the box mechanism for copying objects. You either need to implement an explicit copy constructor (or equivalent), implement `Cloneable` or fiddle with serialization or reflection. So there is no generic solution to your problem. That is all covered by the duplicate. – Mark Rotteveel Mar 03 '17 at 21:32
  • Thanks I will read the thread in details then – Milan Mar 05 '17 at 17:57
  • Hi guys, I have totally rewrite this question, if you have a few minutes, please read it again as it would be really helpful to benefit from your experience Thanks :) – Milan Mar 06 '17 at 15:07

0 Answers0