How can I use a third party Class Object as Hashmap Key? - java

OK I understand the working of equals and hashcode and How they are used in hashmap.
But This question crossed my mind What if I am having a third party object which does'nt have overridden hashcode and equals and I am not even allowed to modify it.
Consider following Class:
//Unmodifiable class
public final class WannaBeKey{
private String id;
private String keyName;
//Can be many more fields
public String getId()
{
return id;
}
public String getKeyName()
{
return id;
}
//no hashcode or equals :(
}
Now I want to make this class as my Hashmap key obviously it won't work without equals and hashcode. I want to know is there any way to handle such cases? I am unable to think of any or I am way over my head..
Thanks.

I've encountered this previously, and worked around it by creating a wrapper for the WannaBeKey as such:
public class WannaBeKeyWrapper {
private final WannaBeKey key;
public WannaBeKeyWrapper(WannaBeKey key) {
this.key = key;
}
public boolean equals(Object obj) {
// Insert equality based on WannaBeKey
}
public int hashCode() {
// Insert custom hashcode in accordance with http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()
}
}
Obviously this changes your Set from Set<WannaBeKey> to Set<WannaBeKeyWrapper>, but you should be able to account for that.

You can create a wrapper for that object which will have the overridden methods. Then you can use the wrapper class as the key of your hash map.

You can wrap the actual object in another instance with the required semantics:
class KeyWrapper {
WannaBeKey key; // constructor omitted
#Override
public int hashCode() {
return key.getId().hashCode();
}
#Override
public boolean equals(Object o) {
// equals method implementation
}
}
Alternatively, you could simply extend the class (if the class was not final as you stated in your edit).

This question has already been answered thoroughly but I thought it was worth mentioning that the solutions above are part of a specific design pattern known as a Decorator.
The Adapter or Wrapper pattern uses essentially the same solution but is meant more for transforming code to a different interface whereas Decorator is used for extension.

Related

How do I create a list of multiple types using an interface?

I have been struggling to grasp this concept in Java. I have a list of objects I need to print. Either a string or bitmap. Each has its own way to be printed. My current interface would look like this:
public interface IPrintJob {
void print();
}
I have PrintJobText, and PrintJobBitmap classes which each implements IPrintJob. I need to be able to add them both to the same list. Can I do it with
ArrayList<IPrintJob> printjobs
Is this the right approach ? Should this be done with generics ? How would PrintJobText/PrintJobBitmap classes look ? I'm a bit lost after trawling the net for an understanding on the best way to handle this.
One example could be like this.. (not completely sure what you mean with a bitmap in this case though, so just made it a boolean)
public interface IPrintJob {
void print();
}
public class PrintJobText implements IPrintJob {
private String text;
PrintJobText(String text) {
this.text = text;
}
void print() {
System.out.println(text);
}
}
public class PrintJobBitmap implements IPrintJob {
private boolean bit;
PrintJobBitmap(boolean bit) {
this.bit = bit;
}
void print() {
System.out.println(bit ? "true" : "false");
}
}
List<IPrintJob> printjobs = new ArrayList<>();
printJobs.add(new PrintJobText("test1");
printJobs.add(new PrintJobBitmap(true);
printJobs.forEach(IPrintJob::print);
Of course the implementation of the print method can be anything. The system out is just an example.
Depends on what you mean by
Each has its own way to be printed
in my opinion. If you just mean what this answer demonstrates, you could also simply override toString() in both of the classes like this:
public class PrintJobText {
private String text;
PrintJobText(String text) {
this.text = text;
}
#Override
public String toString() {
return text;
}
}
public class PrintJobBitmap {
private boolean bit;
PrintJobBitmap(boolean bit) {
this.bit = bit;
}
#Override
public String toString() {
return String.valueOf(bit);
}
}
And simply store the objects in a List<Object> or some other common super-class.
Now does that mean you should do it this way? Probably not. At least don't store the objects in a List<Object>, because what if you wanted to add more functionality to your interface down the line?
Not only would you need to refactor a bunch of type definitions, but before the change nothing would have stopped you from adding instances of classes to the list that don't make any sense to be there, so now you either have to figure out a way to implement the new methods for those classes as well or restructure your code so those classes never get added to the list in the first place.
Another pitfall is that classes could forget to override toString() because there's no way to enforce them to do so.
Another possible definition of the interface could like this:
public interface IPrintJob {
String getPrintValue();
}
This would cut both the problems I mentioned above and is slightly cleaner than having a void print() as it removes the duplication of System.out.println(...) in the implementations.
Create a custom class that could contain attributes of either a string or a bitmap to contain the relevant object but under a different guise I guess, you can then create an array list of these custom objects, and use if ( object instanceof string ) then // do string code, and vice versa for bitmaps.

Responsibility of implementing hashcode and equal

I have an interface called Work
public class interface Work {
boolean completeWork(Job j);
}
Then I have a Composite class
public class CompositeWork implements Work {
private Set<Work> childWork = new HashSet<>();
public boolean completeWork(Job j) {
return childWork.stream().allMatch(w -> w.completeWork(j));
}
public void addWork(Work w) {
childWork.add(w);
}
}
I have a different Work types are the follwoing:
public class EasyWork implements Work {
public boolean completeWork(Job j) {
<do some work>
}
}
public class HardWork implements Work {
private String id;
public Hardwork(String id) {
this.id = id;
}
public boolean completeWork(Job j) {
<do some work>
}
}
Client populate CompositeWork something like this
public class Client {
public static void main(String[] args) {
CompositeWork workHolder = new CompositeWork();
workHolder.add(new EasyWork());
workHolder.add(new EasyWork());
workHolder.add(new HardWork("1"));
workHolder.add(new HardWork("2"));
}
}
To enforce uniqueness of childWork in CompositeWork in HashSet<>() where do i implement hashcode() and equals()?
Does that occur in Work interface?
CompositeWork class?
or is it implemented inside EasyWork and HardWork?
We can't answer the question for you. It depends on how you want the classes to behave.
The default behavior for any class is that different instances will compare unequal to each other. If you are okay with all EasyWork objects being distinct and all HardWork objects being distinct, even when they contain the same data, then you don't need to do anything. The default methods may suffice.
Otherwise, you should examine each class on a case-by-case basis:
If you want HardWork objects to be equal if they have the same id, on the other hand, then you need to override equals() and hashCode() in HardWork. If not, don't bother.
Similarly, if EasyWork objects should be equal to each other then you'll need to override them there as well. If not, don't bother.
Furthermore, if you want CompositeWork objects to be equal to each other if they have the same Set of children then you should override them there, too. If not, don't bother.
Because you need to distinguish between EasyWork & HardWork, you need to implement those methods in those classes.
Here is a good article about this topic.
I see the answer of John Kugelman and I almost agree. Almost - because there is one pretty important thing that is being often forgotten. If you are going to use EasyWork and HardWork objects in a hash-dependant collection like HashSet, besides overriding equals and hashcode you have to make your classes immutable. It means, that
both of your classes have to be final
fields, that are going to used by your equals and hashcode methods, have to be final.
Explanation
If the object is not immutable, then you can change some of its fields, then its hashCode will return a new result, and then you will be unable to access this object in collection due to a wrong location in hashtable.

Facade pattern - return original object or modified original object

I have e.g. object like this:
Original obj = new Original();
And I use from this object e.g. method like(this object has many methods and fields):
obj.getMeYourName();
And I would like to have similar object which is almost same but some methods return something else. I want to solve it by facade.
So, at first I want to create facade and decided if I would return direct object or modified.
What is the best way?
Something like this: ?
Original obj = new Original();
OriginalFacade obj = new OriginalFacade(Original obj, boolean getDirectObject);
OriginalFacade(Original obj, boolean getDirectObject) {
if (getDirectObject) {
return obj //How to convert object into OriginalFacade type?
} else {
obj.setMeYourName("Something else");
return obj; //Howto convert object into OriginalFacade type?
}
}
So, I have 2 problems:
1, is it good solution choose original object or modified original object thru constructor with e.g. boolean getDirectObject?
2, how to easy return original object which must me mapped into OriginalFacade Object
Must I have implement all methods from original object?
Actually, the facade pattern uses a common interface that is used by clients.
For instance:
public interface Facade {
public String getMeYourName();
public void someOtherMethod();
}
public class Original implements Facade {
private String name;
Original(String name) {
this.name = name;
}
public String getMeYourName() {
return name;
}
public void someOtherMethod() {
// a lot of great code
}
}
public class Modified implements Facade {
private Facade original;
private String otherName;
Modified(Facade original, String otherName) {
this.original = original;
this.otherName = otherName;
}
public String getMeYourName() {
return otherName;
}
public void someOtherMethod() {
original.someOtherMethod();
}
}
The clients should only need to see the Facade interface, and shouldn't need to care which actual implementation they are dealing with.
Your code demonstrates you have not understood Facade at all.
In first place Facade should be used to provide a simple interface to complex algorithms.
Second, the facade pattern allows you to access its composed objects, for example:
public class OriginalFacade{
public Original original;
}
Unless you follow the Law of Demeter, this code is perfect valid.
Regardless, if Facade is used, you should not need to access those objects.
The following link explains a little bit of Facade
I recommend you buy and read this book
Facade is not the patter to be used here. It is used to make a complex interface simpler, for example, making out-of-the-box usage patterns.
In your case, why don't you just extend the Original class and overload the methods you want to behave differently?

Extending enum fields Java

I know that it isn't possible to extend enum in Java, but I am trying to find an elegant solution for the below
I am trying to model enums (or classes) which will contain http end points of various web services across regions, say I have service A and B, each will have 4 region specific end points in US, EU, JP or CN. (This is basically for some seperate debug code that I am writing, in production the end points will be picked from configuration)
I was hoping to do something like this (not compliant java code).
public enum IEndPoint {
NA_END_POINT,
EU_END_POINT,
JP_END_POINT,
CN_END_POINT,
}
public enum ServiceAEndPoint extends IEndPoint {
NA_END_POINT("http://A.com/");
EU_END_POINT("http://A-eu.com/");
JP_END_POINT("http://A-jp.com/");
CN_END_POINT("http://A-cn.com/");
}
I could do this using interfaces where I have a method for each region, but in my opinion the enum way is more expressive, is there any better way I could model this ? What I am looking for is if there is any better way to model the inheritence relation and also having the expressive power of enumerations.
ServiceAEndPoint.NA_END_POINT
vs
serviceAEndPoint.getNAEndPoint()
I'm assuming that you will also want a ServiceBEndPoint enum (and similar). In which case I don't think your model really makes that much sense.
IEndPoint is really an enumeration of the kind of environments/regions where a service might be running. It is not an enumeration of the services themselves. Each individual service (A, B or whatever) will have different addresses for each of the regions.
Therefore I would stick with just the IEndPoint enum, and then in some service-specific code have a lookup map that will give you the address for a given end-point. Something like this:
public enum IEndPoint {
NA_END_POINT,
EU_END_POINT,
JP_END_POINT,
CN_END_POINT,
}
public class ServiceABroker {
private static final Map<IEndPoint, String> addressesByEndPoint;
static {
addressesByEndPoint = new EnumMap<>();
addressesByEndPoint.put(NA_END_POINT, "http://A.com/");
addressesByEndPoint.put(EU_END_POINT, "http://A-eu.com/");
addressesByEndPoint.put(JP_END_POINT, "http://A-jp.com/");
addressesByEndPoint.put(CN_END_POINT, "http://A-cn.com/");
}
public String getAddressForEndPoint(IEndPoint ep) {
return addressesByEndPoint.get(ep);
}
}
If these are static final constants, then just put them in an interface. Name the interface something like IServiceAEndPointKeys, where the keys part is a convention.
Here's where I consider enums to be more appropriate and useful:
Example 1: File type. An enum containing jpg, pdf etc.
Example 2: Column definitions. If I have a table with 3 columns, I would write an enum declaring ID, Name, Description (for example), each one having parameters like column header name, column width and column ID.
Im not sure I understand you question, but you can add methods to an enum for example you could do something like the following:
public enum ServiceAEndPoint{
NA_END_POINT("http://A.com/");
EU_END_POINT("http://A-eu.com/");
JP_END_POINT("http://A-jp.com/");
CN_END_POINT("http://A-cn.com/");
private final String url;
private EndPoint(String url){
this.url=url;
}
public String getURL(){
return url;
}
}
Enums cannot be extended in such a manner, mostly because enums cannot be sub-classed or the constraints they must adhere to will not be possible to impose.
Instead leverage interfaces, like so
public interface IEndPoint;
public enum DefaultEndPoints implements IEndPoint {
NA_END_POINT,
EU_END_POINT,
JP_END_POINT,
CN_END_POINT,
}
public enum DefaultServiceEndPoints implements IEndPoint {
NA_END_POINT("http://A.com/");
EU_END_POINT("http://A-eu.com/");
JP_END_POINT("http://A-jp.com/");
CN_END_POINT("http://A-cn.com/");
}
public void doSomething(IEndPoint endpoint) {
...
}
The reason why one can't subclass in the manner you wish is related to the contract that enums will be both equal via .equals(object) and via ==. If you could subclass, would this make sense?
if ( (DefaultEndPoints)JP_END_POINT == (DefaultServiceEndPoints)JP_END_POINT) {
}
if you say "yes" then I would expect to be able to do this
DefaultEndPoint someEndpoint = DefaultServiceEndPoints.JP_END_POINT;
which would leave a door open for error, as there is no guarantee that a enum entry in one enum declaration is in the other enum declaration.
Could it be different? Perhaps, but it isn't, and changing it would definately introduce a lot of complications that would have to be thoroughly thought out (or it would open avenues to work around Java's strong static-type checking).
You may want to consider something like this:
public abstract class EndpointFactory {
public abstract String getNAEndPoint();
public abstract String getEUEndPoint();
}
public class ServiceAEndpointFactory extends EndpointFactory {
public static final String NA_END_POINT = "http://A.com/";
public static final String EU_END_POINT = "http://A-eu.com/";
public String getNAEndPoint() {
return ServiceAEndpointFactory.NA_END_POINT;
}
public String getEUEndPoint() {
return ServiceAEndpointFactory.EU_END_POINT;
}
}
public class ServiceBEndpointFactory extends EndpointFactory {
public static final String NA_END_POINT = "http://B.com/";
public static final String EU_END_POINT = "http://B-eu.com/";
public String getNAEndPoint() {
return ServiceAEndpointFactory.NA_END_POINT;
}
public String getEUEndPoint() {
return ServiceAEndpointFactory.EU_END_POINT;
}
}
Then you can refer to your strings directly like this:
ServiceAEndpointFactory.NA_END_POINT;
Or, you can use the base object if the type of service is not known until execution:
EndpointFactory ef1 = new ServiceAEndpointFactory();
String ep = ef1.getNAEndPoint();
The drawback of this is the redefinition of the get*Endpoint() functions in each sub-class. You could eliminate that by moving the static final variables to be not static in the base class and putting the getter/setter in the base class only one time. However, the drawback of that is you are not able to reference the values without instantiating an object (which essentially emulates what I find valuable with ENUMs).
How does a pattern like this appeal to you? I let the enum implement an interface and implement the interface in a Debug set and a Release set. The release set can then derive the property name from the enum name - which is neat.
public interface HasURL {
public String getURL();
}
public enum DebugEndPoints implements HasURL {
NA,
EU,
JP,
CN;
#Override
public String getURL() {
// Force debug to go to the same one always.
return "http://Debug.com/";
}
}
public enum NormalEndPoints implements HasURL {
NA,
EU,
JP,
CN;
final String url;
NormalEndPoints () {
// Grab the configured property connected to my name.
this.url = getProperty(this.name());
}
#Override
public String getURL() {
return url;
}
}

Java - Method name collision in interface implementation

If I have two interfaces , both quite different in their purposes , but with same method signature , how do I make a class implement both without being forced to write a single method that serves for the both the interfaces and writing some convoluted logic in the method implementation that checks for which type of object the call is being made and invoke proper code ?
In C# , this is overcome by what is called as explicit interface implementation. Is there any equivalent way in Java ?
No, there is no way to implement the same method in two different ways in one class in Java.
That can lead to many confusing situations, which is why Java has disallowed it.
interface ISomething {
void doSomething();
}
interface ISomething2 {
void doSomething();
}
class Impl implements ISomething, ISomething2 {
void doSomething() {} // There can only be one implementation of this method.
}
What you can do is compose a class out of two classes that each implement a different interface. Then that one class will have the behavior of both interfaces.
class CompositeClass {
ISomething class1;
ISomething2 class2;
void doSomething1(){class1.doSomething();}
void doSomething2(){class2.doSomething();}
}
There's no real way to solve this in Java. You could use inner classes as a workaround:
interface Alfa { void m(); }
interface Beta { void m(); }
class AlfaBeta implements Alfa {
private int value;
public void m() { ++value; } // Alfa.m()
public Beta asBeta() {
return new Beta(){
public void m() { --value; } // Beta.m()
};
}
}
Although it doesn't allow for casts from AlfaBeta to Beta, downcasts are generally evil, and if it can be expected that an Alfa instance often has a Beta aspect, too, and for some reason (usually optimization is the only valid reason) you want to be able to convert it to Beta, you could make a sub-interface of Alfa with Beta asBeta() in it.
If you are encountering this problem, it is most likely because you are using inheritance where you should be using delegation. If you need to provide two different, albeit similar, interfaces for the same underlying model of data, then you should use a view to cheaply provide access to the data using some other interface.
To give a concrete example for the latter case, suppose you want to implement both Collection and MyCollection (which does not inherit from Collection and has an incompatible interface). You could provide a Collection getCollectionView() and MyCollection getMyCollectionView() functions which provide a light-weight implementation of Collection and MyCollection, using the same underlying data.
For the former case... suppose you really want an array of integers and an array of strings. Instead of inheriting from both List<Integer> and List<String>, you should have one member of type List<Integer> and another member of type List<String>, and refer to those members, rather than try to inherit from both. Even if you only needed a list of integers, it is better to use composition/delegation over inheritance in this case.
The "classical" Java problem also affects my Android development...
The reason seems to be simple:
More frameworks/libraries you have to use, more easily things can be out of control...
In my case, I have a BootStrapperApp class inherited from android.app.Application,
whereas the same class should also implement a Platform interface of a MVVM framework in order to get integrated.
Method collision occurred on a getString() method, which is announced by both interfaces and should have differenet implementation in different contexts.
The workaround (ugly..IMO) is using an inner class to implement all Platform methods, just because of one minor method signature conflict...in some case, such borrowed method is even not used at all (but affected major design semantics).
I tend to agree C#-style explicit context/namespace indication is helpful.
The only solution that came in my mind is using referece objects to the one you want to implent muliple interfaceces.
eg: supposing you have 2 interfaces to implement
public interface Framework1Interface {
void method(Object o);
}
and
public interface Framework2Interface {
void method(Object o);
}
you can enclose them in to two Facador objects:
public class Facador1 implements Framework1Interface {
private final ObjectToUse reference;
public static Framework1Interface Create(ObjectToUse ref) {
return new Facador1(ref);
}
private Facador1(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework1Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork1(o);
}
}
and
public class Facador2 implements Framework2Interface {
private final ObjectToUse reference;
public static Framework2Interface Create(ObjectToUse ref) {
return new Facador2(ref);
}
private Facador2(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework2Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork2(o);
}
}
In the end the class you wanted should something like
public class ObjectToUse {
private Framework1Interface facFramework1Interface;
private Framework2Interface facFramework2Interface;
public ObjectToUse() {
}
public Framework1Interface getAsFramework1Interface() {
if (facFramework1Interface == null) {
facFramework1Interface = Facador1.Create(this);
}
return facFramework1Interface;
}
public Framework2Interface getAsFramework2Interface() {
if (facFramework2Interface == null) {
facFramework2Interface = Facador2.Create(this);
}
return facFramework2Interface;
}
public void methodForFrameWork1(Object o) {
}
public void methodForFrameWork2(Object o) {
}
}
you can now use the getAs* methods to "expose" your class
You can use an Adapter pattern in order to make these work. Create two adapter for each interface and use that. It should solve the problem.
All well and good when you have total control over all of the code in question and can implement this upfront.
Now imagine you have an existing public class used in many places with a method
public class MyClass{
private String name;
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Now you need to pass it into the off the shelf WizzBangProcessor which requires classes to implement the WBPInterface... which also has a getName() method, but instead of your concrete implementation, this interface expects the method to return the name of a type of Wizz Bang Processing.
In C# it would be a trvial
public class MyClass : WBPInterface{
private String name;
String WBPInterface.getName(){
return "MyWizzBangProcessor";
}
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
In Java Tough you are going to have to identify every point in the existing deployed code base where you need to convert from one interface to the other. Sure the WizzBangProcessor company should have used getWizzBangProcessName(), but they are developers too. In their context getName was fine. Actually, outside of Java, most other OO based languages support this. Java is rare in forcing all interfaces to be implemented with the same method NAME.
Most other languages have a compiler that is more than happy to take an instruction to say "this method in this class which matches the signature of this method in this implemented interface is it's implementation". After all the whole point of defining interfaces is to allow the definition to be abstracted from the implementation. (Don't even get me started on having default methods in Interfaces in Java, let alone default overriding.... because sure, every component designed for a road car should be able to get slammed into a flying car and just work - hey they are both cars... I'm sure the the default functionality of say your sat nav will not be affected with default pitch and roll inputs, because cars only yaw!

Categories

Resources