Kotin Class
class LoginService{
fun getLoginData(loginData: String) {
request(LoginApi.create().getLoginData(loginData))}
}
fun changePassword(_:String){
request(LoginApi.create().changePassword(_)
}
class RequestData {
var retrofitCall: ((String) -> Unit)? = null
}
}
Java Class
class LoginModel{
private void loginData(){
RequestData data = new RequestData();
requestData.setRetrofitCall(username ->LoginService::getLoginData)
}
private void changePassword(){
RequestData data = new RequestData();
requestData.setRetrofitCall(username ->LoginService::changePassword)
}
}
requestData.setRetrofitCall(username ->LoginService::changePassword)
Why Higher order function :
Since i have to differentiate between each API call for calling a function from its feature hence trying to use.
How to call the above highlighted code?
Using Kotlin Functional Interfaces in Java is a little tricky and not very clean.
Your setRetrofitCall() would need to look something like this:
setRetrofitCall(new Function1<String, Unit>() {
#Override
public Unit invoke(String s) {
LoginService.getLoginData(s); //I'm pretty sure LoginService is supposed to be static?
return Unit.INSTANCE;
}
}
);
More short code with Lamda expression
setRetrofitCall(s -> {
LoginService.getLoginData(s);
return Unit.INSTANCE;
});
If you want to use a named class and don't want to refer to Kotlin's interfaces, you can use ::.
class CallbackHandler {
Unit invoke(String s) {
LoginService.getLoginData(s);
return Unit.INSTANCE;
}
}
CallbackHandler handler = new CallbackHandler();
setRetrofitCall(handler::invoke);
Otherwise for anonymous class you can use lambda expression per chakrapani's answer.
setRetrofitCall(s -> {
LoginService.getLoginData(s);
return Unit.INSTANCE;
});
Related
I have the following classes
public class MyCustomFactory extends SomeOther3rdPartyFactory {
// Return our custom behaviour for the 'string' type
#Override
public StringType stringType() {
return new MyCustomStringType();
}
// Return our custom behaviour for the 'int' type
#Override
public IntType intType() {
return new MyCustomIntType();
}
// same for boolean, array, object etc
}
Now, for example, the custom type classes:
public class MyCustomStringType extends StringType {
#Override
public void enrichWithProperty(final SomePropertyObject prop) {
super.enrichWithProperty(prop);
if (prop.getSomeAttribute("attribute01")) {
this.doSomething();
this.doSomethingElse();
}
if (prop.getSomeAttribute("attribute02")) {
this.doSomethingYetAgain();
}
// other properties and actions
}
}
But each custom type class like the string one above might have exactly the same if (prop.getSomeAttribute("blah")) { // same thing; }
Suppose I was to add another attribute, is there a nice way I can avoid having to duplicate if statements in each custom type class that needs it? I can move each if statement to utility class but I still need to add the call to the method in the utility class. I think we can do better.
You can create Map<String, Consumer<MyCustomStringType>>, where the key is your attribute name and value is the method call.
public class MyCustomStringType extends StringType {
private final Map<String, Cosnumer<MyCustomStringType>> map = new HashMap<>();
{
map.put("attribute01", o -> {o.doSomething(); o.doSomethingElse();});
map.put("attribute02", MyCustomStringType::doSomethingYetAgain);
// other properties and actions
}
#Override
public void enrichWithProperty(final SomePropertyObject prop) {
super.enrichWithProperty(prop);
map.entrySet().stream()
.filter(entry -> prop.getSomeAttribute(entry.getKey()))
.forEach(entry -> entry.getValue().accept(MyCustomStringType.this));
}
}
Depending on how you initialise this class (and whether this map is always the same), you might be able to turn in into static final immutable map.
I would also recommend naming it better, but a lot here depends on your domain and what this map and loop actually do.
Using GraphStage is recommended in Akka Streams, but I could not find any documentation on using the getStageActor() method in Java (all of the documentation that I have found used Scala).
How can I convert the following code to Java?
lazy val self: StageActor = getStageActor(onMessage)
and
private def onMessage(x: (ActorRef, Any)): Unit =
{
x match {
case (_, msg: String) =>
log.info("received msg, queueing: {} ", msg)
messages = messages.enqueue(msg)
pump()
}
}
According to the getStageActor method documentation, it accepts a value of type
scala.Function1<scala.Tuple2<ActorRef,java.lang.Object>, scala.runtime.BoxedUnit>
which in Scala looks like
((ActorRef, AnyRef)) => Unit
In Java this type would be semantically equivalent (using the Function interface) to
Function<Tuple<ActorRef, Object>, Void>
where Tuple<A, B> is a class which contains two values of types A and B.
Therefore, to call the getStageActor method, you need to create a value of the aforementioned type. You can do it directly by constructing an instance of a class extending AbstractFunction1:
import scala.Function1;
import scala.Tuple2;
import scala.runtime.AbstractFunction1;
import scala.runtime.BoxedUnit;
getStateActor(new AbstractFunction1<Tuple2<ActorRef, Object>, BoxedUnit>() {
#Override
public BoxedUnit apply(Tuple2<ActorRef, Object> args) {
return BoxedUnit.UNIT;
}
});
If you use Java 8, there are syntactically nicer ways to do it using lambda expressions.
If you use Scala 2.12+, then scala.Function1 is a functional interface, and you can use lambda expressions directly:
getStateActor((args: Tuple2<ActorRef, Object>) -> BoxedUnit.UNIT);
If you use an older version of Scala, then due to the way traits are compiled, Function1 is not a functional interface, and you will need to use the scala-java8-compat library. With it, the code looks like
import static scala.compat.java8.JFunction.*;
getStateActor(func((args: Tuple2<ActorRef, Object>) -> BoxedUnit.UNIT));
Then, to implement the logic of the function, you can access elements of the tuple using the _1() and _2() methods:
(args: Tuple2<ActorRef, Object>) -> {
Object msg = args._2();
if (msg instanceof String) {
log.info("received msg, queueing: {} ", msg);
messages = messages.enqueue((String) msg);
pump();
}
return BoxedUnit.UNIT;
}
This is a direct translation of the logic that you wanted to convert.
I have not used getStageActor() before, hence can't provide much help there. As to code conversion from Scala to Java in general, if requirement allows, package a jar containing the classes of the Scala version for the Java app to use; otherwise consider using a Java decompiler (e.g. cfr, procyon) to decompile your Scala-compiled classes and refine the decompiled Java code as needed.
For example decompiling the following dummy Scala code would help reveal a skeletal Java way of lazy val and pattern matching:
class Foo {
lazy val self = dummy(bar(_: String))
def dummy(u: Unit) = 1
private def bar(x: String): Unit = {
x match {
case "blah" => println(s"x = $x")
}
}
}
As shown in the decompiled code below, lazy val is done in Java with the value wrapped inside a synchronized block with a bitmap$0 boolean flag, and pattern matching gets converted to if and MatchError exception:
$ java -jar /path/to/decompiler/cfr_0_125.jar Foo.class
private int self;
private volatile boolean bitmap$0;
private int self$lzycompute() {
Foo foo = this;
synchronized (foo) {
if (!this.bitmap$0) {
new Serializable(this){
public static final long serialVersionUID = 0L;
private final /* synthetic */ Foo $outer;
public final void apply(String x$1) {
this.$outer.Foo$$bar(x$1);
}
{
if ($outer == null) {
throw null;
}
this.$outer = $outer;
}
};
this.self = this.dummy(BoxedUnit.UNIT);
this.bitmap$0 = true;
}
return this.self;
}
}
public int self() {
return this.bitmap$0 ? this.self : this.self$lzycompute();
}
public int dummy(BoxedUnit u) {
return 1;
}
public void Foo$$bar(String x) {
String string = x;
if ("blah".equals(string)) {
Predef$.MODULE$.println((Object)new StringContext(
(Seq)Predef$.MODULE$.wrapRefArray((Object[])new String[]{"x = ", ""})
).s((Seq)Predef$.MODULE$.genericWrapArray((Object)new Object[]{x}))
);
BoxedUnit boxedUnit = BoxedUnit.UNIT;
return;
}
throw new MatchError((Object)string);
}
I have the following code:
public interface Logic
{
boolean logicAccesscible();
}
public class LocationLogic implements Logic
{
#Override
public boolean logicAccesscible()
{
return true;
}
}
But when I try to use a lambda to create a LocationLogic object it simply won't work.
l.setLocationLogic(new LocationLogic()
{
#Override
public boolean logicAccesscible()
{
return false;
}
});
that snipet works, but
l.setLocationLogic(() ->
{
return false;
});
Gives me the error of "Target type of lambda conversion must be an interface"
And yes, I've tried to use:
l.setLocationLogic((LocationLogic) () -> {return false;});
You get this error because, you can only create lambdas from functional interfaces, which just means an interface with exactly one abstract method.
Now your setLocationLogic expects a LocationLogic (a class) and java forbids the creation of lambdas from classes. thats why your first snippet works, but your second doesn't.
Either change the signature of setLocationLogic to setLocationLogic(Logic logic).
Or maybe create a constructor in LocationLogic which accepts a boolean, which you then return in the implemented function:
public class LocationLogic implements Logic{
private final boolean accessible;
public LocationLogic(boolean accessible){
this.accessible = accessible;
}
public boolean logicAccessible(){
return accessible;
}
}
That way you could use it like:
l.setLocationLogic(new LocationLogic(false));
I have following code:
public class A {
private String type;
String getType() { return type;}
}
Now in many code places I have code like this
switch (a.geType()) {
case "A" : return new Bla();
case "B" : return new Cop();
}
or somewhere else
switch (a.geType()) {
case "A" : return new Coda();
case "B" : return new Man();
}
(Note that I know I should use an Enumeration in production code).
What I want to achive is that when a new type is added to class A the compiler should flag all the switch statements that need to be adjusted?
Is there a java idiomatic way to do this?
when a new type is added to class A the compiler should flag all the switch statements that need to be adjusted?
A good approach to this would be replacing switch statements with a more robust implementation of multiple dispatch, such as the Visitor Pattern:
interface VisitorOfA {
Object visitA(A a);
Object visitB(B b);
}
class A {
Object accept(VisitorOfA visitor) {
return visitor.visitA(this);
}
}
class B extends A {
Object accept(VisitorOfA visitor) {
return visitor.visitB(this);
}
}
With this infrastructure in place, you can remove your switch statements, replacing them with implementations of the visitor:
Object res = a.accept(new VisitorOfA() {
public Object visitA(A a) { return new Bla(); }
public Object visitB(B b) { return new Cop(); }
});
When you add a new subtype to A, say, class C, all you need to do is adding a new method to VisitorOfA:
Object visitC(C c);
Now the compiler will spot all places where this new method has not been implemented, helping you avoid problems at runtime.
Don't forget about good old-fashioned polymorphism. Having a "type" field with switch statements in a class is often a smell that indicates that subclassing might be useful. Consider:
public abstract class CommonSuperClass {
public abstract One getOne();
public abstract Two getTwo();
}
public class A extends CommonSuperClass {
#Override public One getOne() { return new Bla(); }
#Override public Two getTwo() { return new Coda(); }
}
public class B extends CommonSuperClass {
#Override public One getOne() { return new Cop(); }
#Override public Two getTwo() { return new Man(); }
}
If you were to add a new subclass C, you're required to provide implementations for the abstract methods (unless you make C itself be abstract).
You could have a map of string / suppliers:
Map<String, Supplier<Object>> map = new HAshMap<> ();
map.put("A", Bla::new);
map.put("B", Cop::new);
And your sample code would become:
return map.get(a.getType()).get(); //need null check
In perspective of abstraction, there is another approach for you to use. One way is via Polymorphism as shown here.
Some simple example:
public void EverythingYouWant (Animal animal) {
return animal.move();
}
When it's more about refactoring replace type code/checking with State/Strategy patterns. It's good solution to first consider is there any reason that prevents subclassing.
I'd like to ask for help and some suggestion how to refactor source code which I receive.
Here is pseudocode of my method:
public void generalMethod(String type) {
InputParameters params = new InputParameters();
if (type.equals("someKey1"){
decodeSomeKey1(params);
} else if (type.equals("someKey2"){
decodeSomeKey2(params);
} else if (type.equals("someKey3"){
decodeSomeKey3(params);
} else if (type.equals("someKey4"){
etc...
}
}
}
All methods have the same input parameters. In first step I created new interface and created for each method separate class which implements created interface.
interface ISomeInterfaceDecoder {
void decode(InputParameters params);
}
class DecodeSomeKey1 implements ISomeInterfaceDecoder {
#Override
public void decode(InputParameters params) {
// some implementation
}
}
class DecodeSomeKey2 implements ISomeInterfaceDecoder {
#Override
public void decode(InputParameters params) {
// some implementation
}
}
Then I created factory class as follows:
class Factory {
ISomeInterfaceDecoder getDecoder(String type) {
if (type.equals("someKey1"){
return new DecodeSomeKey1();
} else if (type.equals("someKey2"){
return new DecodeSomeKey2();
} else if (type.equals("someKey3"){
return new DecodeSomeKey3());
} else if (type.equals("someKey3"){
etc...
}
}
}
}
After these changes the code looks like this:
class SomeClass {
Factory factory = new Factory();
public void generalMethod(String type) {
InputParameters params = new InputParameters();
ISomeInterfaceDecoder decoder = factory.getDecoder(type);
decoder.decode(params);
}
}
Code of this method looks better but...
This method is called very very often. Each time a new instance of the given class is created. This can cause performance problems. So, I think it's not good approach to this problem.
Can you give me some suggestion how I should to refactor this code?
Thanks in advance for help.
Instead of having a key as a String, make it an enum. Then in the enum you can implement the decode() method like this:
public enum MyKeyEnum {
VALUE1 {
public void decode(InputParameters ip) {
// do specific decoding for VALUE1
}
},
VALUE2 {
public void decode(InputParameters ip) {
// do specific decoding for VALUE2
}
}
...
;
public abstract void decode(InputParameters ip);
}
Now in the calling code you can do something like this:
public void generalMethod(MyKeyEnum type) {
InputParameters params = new InputParameters();
type.decode(params);
}
The advantage is that all the decode methods are in 1 enum, you dont need a specific class for each of the decoders. Also when a new value is added to the enum, you cannot forget to implement the decode method (or it will not compile).
Can you give me some suggestion how I should to refactor this code?
I see no mention of automated regression testing, and that would be my first step, to put in a test suite (via, say, JUnit or TestNG) before going further.
After that, I'd perhaps introduce a Map of String keys to Decoder objects.
But put the test framework in first. Otherwise you'll never really know if you've introduced bugs or different modes of operation.
Introduce caching/singletons in your factory, that you only return an algorithm once. Also, make your factory a singleton.
Create a static Map<String, ISomeInterfaceDecoder> where you map the identifier to algorithms executing the call which means no factory class and no algorithm instantiation. Works only, if you have stateless algorithms.