I have a Functional Interface in the code below which has one abstract method and one object method override. So when I write Lambda expression for that , how can I implement my equals method.
import static java.lang.System.out;
public class Test {
public static void main(String[] args) {
AddToString test = a -> (a + " End");
out.println(test.stringManipulation("some string"));
out.println(test.increment(5));
out.println(test.equals(null));
}
}
#FunctionalInterface
interface AddToString {
String stringManipulation(String a);
default int increment(int a) { return a+1; }
#Override
public boolean equals(Object obj);
}
One way to do that is to create Anonymous class like given below, but is there a better method using lambda expressions -
public class Test {
public static void main(String[] args) {
AddToString test = new AddToString() {
public String stringManipulation(String a) {
return a + " End";
}
#Override
public boolean equals(Object Obj) {
//Just testing whether it overrides
return 5==5;
}
};
out.println(test.stringManipulation("some string"));
out.println(test.increment(5));
out.println(test.equals(null));
}
}
You can't. If you need to override equals, you'll need to create a class (anonymous or otherwise), you can't do it with a lambda.
Related
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
public class B extends A {
#Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
#Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.f1("Hello");
}
}
I'm seeking that this code would output:
B.f1(String)
A.f1(String)
A.f1(int, String)
Yet I'm getting:
B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)
I understand that under the context of B "this" in A.f1(String) is B's instance.
Do I have the option to do the chain new B1().f1(String) -> (A's) f1(String) -> (A's) f1(int, String) ?
This is a theoretical question, practically the solution would obviously be in A to implement a private function that both f1(String) and f1(int, String) would call.
Thank you,
Maxim.
Unfortunately, no
As i'm sure you're aware, but I'll state explicitly for completeness - there are only the 2 keywords to control the method invocation:
this - this.method() - looks for method starting from the invoking instance's class (the instance's "top" virtual table - implied default)
super - super.method() - looks for method starting from the parent class of the class in which the invoking method is defined (the invoking class' parent's virtual table - not strictly true, but simpler to think of this way - thanks #maaartinus)
I can imagine another keyword (e.g. current?) do what you describe:
current - current.method() - looks for method starting from the class in which the invoking method is defined
but Java doesn't have such a keyword (yet?).
I'm afraid, it's impossible, but there's a simple workaround:
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
privateF1(1, str);
}
private void privateF1(int i, String str) {
System.out.println("A.f1(int, String)");
}
public void f1(int i, String str) {
privateF1(i, str);
}
}
Overridden methods in Java are dynamically bound. i.e. the type of the actual instance of the object dictates what will be called. final methods (which can't be overridden) and private methods (which can't be inherited) are statically bound.
In C++, for contrast, you'd have to explicitly make the functions virtual to get the same behaviour.
package main;
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
if (this instanceof B)
new A().f1(1, str);
else
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
class B extends A {
#Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
#Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
public static void main(String[] args) {
A a = new B();
a.f1("Hello");
}
}
I am a beginner and i try to teach myself clean coding. I want to pass a function as a parameter that I can reuse a method without to repeat code. As an example I have this:
public class Dog {
private String name;
private int id;
private List<String> characteristic;
public List<String> getCharacteristic() {
return characteristic;
}
public void setCharacteristic(List<String> characteristic) {
this.characteristic = characteristic;
}
}
public class Check{
private List<Dog> dogs = new ArrayList();
public void iterate() {
while (dogs.size() > 0) {
for (Dog dog : dogs) {
List<String> restChara = new ArrayList<>();
restChara= checkChara(dog, restChara);
if (restChara.size()>0) {
dog.setCharacteristic(restChara);
} else {
dogs.remove(dog);
}
}
}
}
private List<String> checkChara(Dog dog, List<String> restChara) {
for (String chara : dog.getCharacteristic()) {
boolean charaChecked = doSomething(chara);
if (!charaChecked) {
restChara.add(chara);
} else {
dog.getCharacteristic().remove(chara);
}
}
return restChara;
}
private boolean doSomething(String chara){
//do sth.
return true;
}
private boolean doSomething2(String chara){
//do sth.
return true;
}
}
How would you define the method checkChara in order to use different functions within it?
My first thought was to pass the function as a parameter (i think it would be in C# delegates)
Thank you very much!
EDIT:
I think I found another pattern strategy design pattern
https://www.freecodecamp.org/news/the-strategy-pattern-explained-using-java-bc30542204e0/
Java does not support “directly” nested methods. Many functional programming languages support method within method. But you can achieve nested method functionality in Java 7 or older version by define local classes, class within method so this does compile. And in java 8 and newer version you achieve it by lambda expression.
Method 1 (Using anonymous subclasses)
It is an inner class without a name and for which only a single object is created. An anonymous inner class can be useful when making an instance of an object with certain “extras” such as overloading methods of a class or interface, without having to actually subclass a class.
//Java program implements method inside method
public class GFG {
// create a local interface with one abstract
// method run()
interface myInterface {
void run();
}
// function have implements another function run()
static void Foo()
{
// implement run method inside Foo() function
myInterface r = new myInterface() {
public void run()
{
System.out.println("geeksforgeeks");
};
};
r.run();
}
public static void main(String[] args)
{
Foo();
}
}
Method 2 (Using local classes)
You can also implement a method inside a local class. A class created inside a method is called local inner class. If you want to invoke the methods of local inner class, you must instantiate this class inside method.
// Java program implements method inside method
public class GFG {
// function have implementation of another
// function inside local class
static void Foo()
{
// local class
class Local {
void fun()
{
System.out.println("geeksforgeeks");
}
}
new Local().fun();
}
public static void main(String[] args)
{
Foo();
}
}
Method 3 (Using a lambda expression)
Lambda expressions basically express instances of functional interfaces (An interface with single abstract method is called functional interface. An example is java.lang.Runnable). lambda expressions implement the only abstract function and therefore implement functional interfaces.
// Java program implements method inside method
public class GFG {
interface myInterface {
void run();
}
// function have implements another function
// run() using Lambda expression
static void Foo()
{
// Lambda expression
myInterface r = () ->
{
System.out.println("geeksforgeeks");
};
r.run();
}
public static void main(String[] args)
{
Foo();
}
}
I don't exaclty know what you mean, but i figure out it could be something like that:
List<Runnable> runMyStuff = new ArrayList<Runnable>();
String variable= "Hallo"; //needs to be effectively final
runMyStuff.add(() -> {
System.out.println(variable);
doSomething(variable);
});
runMyStuff.add(() ->{
System.out.println("This is a test");
});
runMyStuff.add(() ->{
System.out.println("2 + 2 = " + (2+2) );
});
runMyStuff.get(0).run();
runMyStuff.get(2).run();
runMyStuff.get(0).run();
runMyStuff.get(1).run();
runMyStuff.get(2).run();
will result in :
Hallo
2 + 2 = 4
Hallo
This is a test
2 + 2 = 4
When you put variables or Passing Parameters in those runnable methods, they need to be effectively final or you pass them in a container.
You can re-run each method.
And within those Methods you can execute other methods.
NOTE:
If you want to have return Parameters you could do the same with Callable and than ".call()" instead of run.
EDIT:
Under the assumption you mean character Check or something like that
Example for charaCheck passable Method With Interface:
public interface CharacterChecker{
//is a template returns boolean, need a String param
public boolean call(String chara);
}
A method that executes a passes method of the type of "CHaracterChecker"
public static void excecutePassedMethod(CharacterChecker checker, String chara) {
System.out.println(chara + ": " + checker.call(chara));
}
Two different implementations of a "Character Checker"
CharacterChecker goodChecker = new CharacterChecker() {
#Override
public boolean call(String chara) {
return "good".equals(chara);
}
};
CharacterChecker lazyCheker = new CharacterChecker() {
#Override
public boolean call(String chara) {
return "lazy".equals(chara);
}
};
The Methods that are Passed the "method" (More like anonymos class object with the method)
excecutePassedMethod(goodChecker, "bad");
excecutePassedMethod(goodChecker, "good");
excecutePassedMethod(goodChecker, "jolly");
excecutePassedMethod(lazyCheker, "frisky");
excecutePassedMethod(lazyCheker, "lazy");
result will be:
bad: false
good: true
jolly: false
frisky: false
lazy: true
Is it possible to overload Enum abstract method?
I have tried this in my code with no effect.
Presented class
public class Test {
public void test(String string){
System.out.println(string);
}
public void test(Object object){
System.out.println("Test1");
}
public static void main(String[] args) {
Object object = new Object();
test.test(object);
test.test("what if?");
}
}
gives expected result of
Test1
what if?
while enum
public enum TestEnum {
TEST1{
public void test(String string){
System.out.println(string);
}
public void test(Object object){
System.out.println("Test1");
}
},
TEST2{
public void test(Object object){
System.out.println("Test2");
}
};
public abstract void test(Object object);
}
public class Test {
public static void main(String[] args) {
Object object = new Object();
TestEnum.TEST1.test("what if?");
TestEnum.TEST1.test(object);
}
}
returns
Test1
Test1
Is it even possible to overload Enum methods or am I doing something wrong? Or maybe should I check for type inside of overriden method and then act accordingly? But then I remove switch statement only to introduce another switch statement.
The thing about enums is that values with bodies are implemented as anonymous subclasses of TestEnum; so they look like this:
final TestEnum TEST1 = new TestEnum() { /* body */ };
Whilst the concrete class of TEST1 is, say TestEnum$1 (or whatever name the compiler decides to give it), the reference is of type TestEnum, so any code outside the body of TEST1 can only access methods defined on TestEnum.
Yes is possible, you are somehow not implementing that in a particular way....
you should
define an interface with the methods you want to override
interface Ifoo {
public void test(Object object);
public void test(String object);
}
then remove the abstract method of the enum and make the enum implement that interface, but override those methods in every constant of the enumerator...
enum TestEnum implements Ifoo {
TEST1 {
#Override
public void test(String string) {
System.out.println(string);
}
#Override
public void test(Object object) {
System.out.println("Test1");
}
},
TEST2 {
#Override
public void test(Object object) {
System.out.println("Test2");
}
#Override
public void test(String string) {
System.out.println(string);
}
};
}
finally implement it like>
Object object = new Object();
TestEnum.TEST1.test("what if?");
TestEnum.TEST1.test(object);
TestEnum.TEST2.test("why not?");
TestEnum.TEST2.test(object);
your result should looks like:
what if?
Test1
why not?
Test2
You are showing an example with a class and then you are showing an example with an enum. I believe you think these examples are equivalent, however, they are completely different each other.
For the example of your class to be equivalent to the example of your enum, you should modify your Test class so that it extends an abstract AbstractTest class:
public abstract class AbstractTest {
public abstract void test(Object object);
}
public class Test extends AbstractTest {
public void test(String string) {
System.out.println(string);
}
#Override
public void test(Object object) {
System.out.println("Test1");
}
}
Now, if you try the same lines you've tried in your first main:
AbstractTest test = new Test();
Object object = new Object();
test.test(object);
test.test("what if?");
You'll notice that the output has now become:
Test1
Test1
Which is something to be expected, because Java doesn't provide a feature called dynamic dispatch. Informally, dynamic dispatch means that the overloaded method to be executed is decided at runtime, based on the polymorphic types of the parameters. Instead, Java decides the method to be executed at compilation time, based on the declared type of the object whose method is to be invoked (in this case AbstractTest).
With enums, this is exactly what happens. All the elements of the enum (TEST1 and TEST2 in your example) belong to the type of the enum (TestEnum in your case), so the compiler always goes for the method that is declared as abstract.
The reason why you get twice "Test1" is because you have declared only this method
public abstract void test(Object object);
Precisely, this method will "catch" all calls whit any type of parameter. String extends Object (indirectly), so String is Object and this method we be called.
In other words, method wich receives parameter String will be hidden by the method which receives parameter Object.
The solution is to add next method declaration in enum
public abstract void test(String string);
You will have to add the implementation of this method to TEST2 constant.
Code
public enum TestEnum {
TEST1 {
public void test(String string) {
System.out.println(string);
}
public void test(Object object) {
System.out.println("Test1");
}
},
TEST2 {
public void test(Object object) {
System.out.println("Test2");
}
#Override
public void test(String string) {
// TODO Auto-generated method stub
}
};
public abstract void test(Object object);
public abstract void test(String string);
}
This code gives output
what if?
Test1
I've been dealing with a domain issue where I have classes that implement a common interface and I want to be able to get hashes from these objects differently depending on if the object is accessed as an interface or as a concrete class instance. Basically what I want is the following:
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
public class B implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
public class C implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
Bar interfaceObject = new A();
interfaceObject.hashCode(); //return 123
Bar aObject = new A();
aObject.hashCode();// return 1
As far as I know there isn't a way to do this, and I can think of lots of reasons why this could cause issues, but I wanted to ask those smarter than I if they had any nice ways of doing this outside of making the interface have a function like public int getCustomHashCodeForJustThisInterface(). I like being able to use these objects in hashMaps without having to jump through hoops, but with their current implementation of hashCode they would break, since these objects can have multiple views of their identity depending on how they are used, and I don't want to change their base implementation of hashCode;
You can't do that, because Java does not support non-polymorphic instance methods (static methods are not polymorphic, as the previous answer showed).
What you can do is to make your classes not directly implement Bar, but another interface (e.g. BarProvider) with a toBar() or getBar() method, which returns a custom object of type Bar, which behaves as you want.
public class A implements BarProvider{
#Override
public int hashCode(){ return 1;}
#Override
public Bar toBar() {
return new Bar() {
#Override
public int hashCode() { return 123; }
};
}
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
Bar interfaceObject = aObject.toBar();
interfaceObject.hashCode(); // return 123
Several improvements are possible, such as having the Bar object stored as a final field (to avoid multiple initializations), and having a reverse reference that allows you to get back from the Bar to its BarProvider.
Another possibility is to use an external provider, that makes your computations
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
}
public final class BarHasher implements Hasher<Bar> }
#Override
public int hashFor(Bar object) { return 123; }
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
BarHasher.hashFor(aObject); // return 123
or a static method that calls some other method
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int hashAsBar() { return 123; }
}
public interface BarHasher implements Hasher<Bar> {
#Override
public int hashFor(Bar object) { return object.hashAsBar(); }
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
BarHasher.hashFor(aObject); // return 123
In case you don't know it, what you're trying to do is possible (and it's the default behavior) in C++ (you must declare methods as virtual to have the same behavior as Java) and in C# (but you will have a warning, unless you use the modifier new on the overriding method)
There's no way to do this that I know of.
Here's something you can do that you may not have known of (I'm not suggesting this is a good idea):
package com.sandbox;
import java.io.IOException;
public class Sandbox {
public static void main(String[] args) throws IOException {
A.speak();
B.speak();
A a = new A();
a.speak(); //my ide rightly gives a warning here. static function accessed through instance
A b = new B();
b.speak(); //my ide rightly gives a warning here. static function accessed through instance
}
public static class A {
public static void speak() {
System.out.println("A");
}
}
public static class B extends A {
public static void speak() {
System.out.println("B");
}
}
}
This will print:
A
B
A
A
Just to reiterate: This is NOT a good idea. I'm just letting you know for educational purposes.
It's easy to invoke different methods based on the declared type of a variable. That's called overriding, and here's an example of it:
public class Example {
public static void main(String[] argv) throws Exception {
Integer v1 = 12;
Number v2 = v1;
System.out.println(v1.hashCode() + " -> " + new KeyWrapper(v1).hashCode());
System.out.println(v2.hashCode() + " -> " + new KeyWrapper(v2).hashCode());
}
private static class KeyWrapper {
private Object obj;
private int hash;
public KeyWrapper(Integer v) {
this.hash = v.hashCode() * 3;
}
public KeyWrapper(Number v) {
this.hash = v.hashCode() * 5;
}
#Override
public int hashCode() {
return hash;
}
}
}
When you run this, you get the following output:
12 -> 36
12 -> 60
Why this is a bad idea is that you can't implement equals() in in a way that preserves its contract (which is that two equal objects must have equal hashcodes). At compile-time you have information about how the values are referenced, but at runtime you only know what they are.
That said, if you want to use different hashcode calculations for objects that do implement an interface, versus those that don't, you can write a KeyWrapper that uses instanceof.
public class Example {
public static void main(String[] argv) throws Exception {
Integer v1 = 12;
String v2 = "foo";
System.out.println(v1.hashCode() + " -> " + new KeyWrapper(v1).hashCode());
System.out.println(v2.hashCode() + " -> " + new KeyWrapper(v2).hashCode());
}
private static class KeyWrapper {
private Object wrapped;
public KeyWrapper(Object obj) {
this.wrapped = obj;
}
#Override
public boolean equals(Object obj) {
return wrapped.equals(obj);
}
#Override
public int hashCode() {
return (wrapped instanceof Number) ? wrapped.hashCode() * 3 : wrapped.hashCode() * 5;
}
}
}
This, of course, doesn't care about the declared type of the variable, only its actual type.
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
public class B extends A {
#Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
#Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.f1("Hello");
}
}
I'm seeking that this code would output:
B.f1(String)
A.f1(String)
A.f1(int, String)
Yet I'm getting:
B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)
I understand that under the context of B "this" in A.f1(String) is B's instance.
Do I have the option to do the chain new B1().f1(String) -> (A's) f1(String) -> (A's) f1(int, String) ?
This is a theoretical question, practically the solution would obviously be in A to implement a private function that both f1(String) and f1(int, String) would call.
Thank you,
Maxim.
Unfortunately, no
As i'm sure you're aware, but I'll state explicitly for completeness - there are only the 2 keywords to control the method invocation:
this - this.method() - looks for method starting from the invoking instance's class (the instance's "top" virtual table - implied default)
super - super.method() - looks for method starting from the parent class of the class in which the invoking method is defined (the invoking class' parent's virtual table - not strictly true, but simpler to think of this way - thanks #maaartinus)
I can imagine another keyword (e.g. current?) do what you describe:
current - current.method() - looks for method starting from the class in which the invoking method is defined
but Java doesn't have such a keyword (yet?).
I'm afraid, it's impossible, but there's a simple workaround:
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
privateF1(1, str);
}
private void privateF1(int i, String str) {
System.out.println("A.f1(int, String)");
}
public void f1(int i, String str) {
privateF1(i, str);
}
}
Overridden methods in Java are dynamically bound. i.e. the type of the actual instance of the object dictates what will be called. final methods (which can't be overridden) and private methods (which can't be inherited) are statically bound.
In C++, for contrast, you'd have to explicitly make the functions virtual to get the same behaviour.
package main;
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
if (this instanceof B)
new A().f1(1, str);
else
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
class B extends A {
#Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
#Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
public static void main(String[] args) {
A a = new B();
a.f1("Hello");
}
}