-4

Suppose I need to create a multi-set data structure with operations such as intersect and union of two sets. With c# or java.

In both cases I need create a copy of every object of both sets, otherwise changing one of it could break other sets.

I see one solution: specify generic type, for example

class MultiSet<T, U> where T : struct, where U : ICloneable

or something like this in java.

Are there another ways to solve this?

llvk
  • 248
  • 2
  • 13
  • I see the reason for why you'd want to clone objects, but keep in mind that IClonable in C# is considered bad (see e.g. http://stackoverflow.com/questions/536349/why-no-icloneablet). Although I'm not a Java developer, I'm almost certain that Java doesn't support structs. – SimonAx Jun 13 '14 at 14:35
  • Using the cloneable interface in java has a pretty bad code smell, imo. – Andreas Jun 13 '14 at 14:36
  • The answer to your question is "Deep cloning". It's a major PITA and generally considered bad practice. Would you care to explain why you think it would be a bad thing if state changes in one set, affect the others? I can't think of a reason why. Also, an Object that implements IClonable (which is a shallow clone IIRC) or has a copy constructor by definition, cannot also be arbitrary. – Mikkel Løkke Jun 13 '14 at 14:38

2 Answers2

3

In both cases I need create a copy of every object of both sets, otherwise changing one of it could break other sets

If you want an intersect of two collections of objects, you will want references to those that "match" as a result, rather than copies of them. The latter makes no sense.

To check wether two objects are the same (in set 1 and set 2), just compare them in a meaningful way (i.e. overriding their hash code and compare methods).

The structure of your result collection will also depend on wether or not the objects can be equal to each other without their reference being equal. In that case, the resulting collection will need to hold two references (two for each "match"), one for each set.

As for the union, just simply create one collection that holds references to all the objects in both collections.

Complete side note

Union and intersect are data operations, and so I assume your collections will hold data. It's not the best idea to do such operations in a programming language. There are other tools that are much more up to the task, such as SQL.

MarioDS
  • 12,895
  • 15
  • 65
  • 121
1

Other than the recommended ICloneable? (I say the recommended way, however cloning is usually seen as bad)

I suppose if the objects are Serializable you could serialize and de-serialise as a new object.

    var formatter = new BinaryFormatter();
    var stream = new MemoryStream();
    using (stream)
    {
        formatter.Serialize(stream, yourObject);
        stream.Seek(0, SeekOrigin.Begin);
        return (YourObjectType)formatter.Deserialize(stream);
    }

Add a null check and it would make a nice extension method for serialisable objects.

Once again though, cloning probably is not a good solution for your problem, but I don't know enough about your use-case to recommend anything.

Nathan Cooper
  • 6,262
  • 4
  • 36
  • 75