I'm trying to learn Java Lamdas.
I'm trying to convert the following code into lambda representation but it's not working:
private void foo(Data data) {
Observable.just(data).subscribeWith(new DisposableObserver<Data>() {
int count = 0;
int pageCount = 0;
#Override
public void onNext(Data data) {
Timber.e("onNext()");
count = data.getCount();
pageCount = data.getPage();
}
#Override
public void onError(Throwable e) {
e.printStackTrace();
}
#Override
public void onComplete() {
Log.e("class", "onComplete");
abc(count, pageCount);
}
});
}
private void bar(Data data) {
Observable.just(data).subscribeWith({
int count = 0;
int pageCount = 0;
data -> {
Timber.e("onNext()");
count = data.getCount();
pageCount = data.getPage();
},
e -> e.printStackTrace(),
() -> {
Log.e("class", "onComplete");
abc(count, pageCount);
}
});
}
This is giving me error. I'm not really sure how to fix it.
You missed one essential part. You can't just turn any anonymous inner class instantiation into a lambda.
Quoting from here:
The major benefit of java 8 functional interfaces is that we can use lambda expressions to instantiate them and avoid using bulky anonymous class implementation.
The core property of a functional interface: it has one single abstract method.
More details can be found here for example.
Beyond that, I think the real answer is on a meta level: you have to understand what you are doing. Meaning: you don't use this or that concept because you heard about it, and someone said: "that is great". You use it because it makes sense in your context.
And of course, you can only decide whether something is useful, "the right thing" ... when you understand that concept. In other words: the real answer is to step back (for now); and study the concept of lambdas first. And to then decide where using it will give benefits to your code base.
Finally: as expressed by user Holger in the comments - there is another no-go in that inner class; as it contains fields; which are even "shared" by some of the methods; another aspect that prevents transforming this class into a single pure lambda.
Related
Just a quick question regarding good programming practices,
Performance aside, how much of a good/bad idea could something like this be?
I am oversimplifying the problem to get my point across, but is something like this totally wrong?
public void methodWithInputString(String data) {
// do something with data
}
public void methodThatCallsTheAbove() {
methodWithInputString(
// lambda with no input and a string as output
(() -> {
if (this.conditionIsTrue)
return "Condition is true";
else
return "Condition is false";
}).apply();
);
}
The alternative would simply be:
public void methodThatCallsTheAbove() {
if (this.conditionIsTrue)
methodWithInputString("Condition is true");
else
methodWithInputString("Condition is false");
}
I understand that the second is the obvious/correct approach but in a situation where using the first one makes my code cleaner is it still a nonsensical thing to do?
+1 for Andy Turner remark.
Plus: Avoid object properties reference inside your lambda.
I guess a compilable version of what you are trying to show would be like this:
public class Demo {
private static final Function<Boolean, String> GET_STRING_DEPENDING_ON_BOOLEAN = flagValue -> "Condition is ".concat(String.valueOf(flagValue));
private boolean conditionIsTrue;
public void methodWithInputString(final String data) {
// do something with data
}
public void methodThatCallsTheAbove() {
methodWithInputString(GET_STRING_DEPENDING_ON_BOOLEAN.apply(this.conditionIsTrue));
}
}
The only advantage of doing this (using a lambda instead of a method) is to be able to re use this lambda and chaining something else with.
Example:
methodWithInputString(GET_STRING_DEPENDING_ON_BOOLEAN.andThen(data -> data.concat("somethingelse")).apply(this.conditionIsTrue));
Sorry, this might be duplicated, I'm not sure if my previous attempt to post this went through.
Started to learn Java several weeks ago, working on one of my first assignments. :)
My question is somewhat basic, but I couldn't find its exact equivalent after looking through previously resolved topics. This isn't a real life problem, so I guess it's expected from me to tackle it in a very specific way.
So the task consisted of several steps - I had to create a superclass with a number of custom objects, add new subclasses, implement new methods to count the value of certain variables, write test classes and sort my output.
It's all been done apart from this last step. Not sure if I'm allowed to just post my problems like that on the web, but here is where I am right now:
I have something like:
public class Pants
{
public enum SizeType {SMALL, MEDIUM, LARGE, EXTRA_LARGE}
private SizeType size;
private String brand;
private String countryOfOrigin;
private String color;
private double price;
//Other variables and methods
}
public class Jeans extends Pants
{
//new variables and methods
}
public class Shorts extends Pants
{
//some more new variables and methods
}
And other similar subclasses.
import java.util.ArrayList;
public class Selection
{
public static void main(String[] args){
Jeans ex1 = new Jeans("John Lewis");
ex1.countryOfOrigin("US");
ex1.color("Navy");
ex1.setSize(Pants.SizeType.LARGE);
ex1.setprice(40);
ex1.machineWashable(true);
System.out.println(ex1);
Shorts ex2 = new Shorts("Ted Baker");
ex2.countryOfOrigin("United Kingdom");
ex2.color("White");
ex2.setSize(Pants.SizeType.MEDIUM);
ex2.setprice(30);
ex2.machineWashable(true);
System.out.println(ex2);
//..etc
ArrayList<Pants> selection = new ArrayList<Pants>();
selection.add(ex1);
selection.add(ex2);
selection.add(ex3);
selection.add(ex4);
selection.add(ex5);
System.out.println( "Size - LARGE: " );
System.out.println();
Pants.SizeType size;
size = Pants.SizeType.LARGE;
ListPants(selection,size);
I need to write a ListPants method to list objects depending on SizeType - starting with large in this case. I don't think I can implement any additional interfaces (which is what was mostly recommended in other threads).
Please see my attempt below (didn't work). Am I thinking in the right direction here, or?
public static void ListPants(ArrayList<Pants> selection, Pants.SizeType size)
{
for (Pants.SizeType sizeType : Pants.SizeType.values()) {
for (Pants pants : selection) {
if (pants.getSize().equals(sizeType)) {
System.out.println(selection.toString());
I think it's just a minor problem you're facing. You already defined the signature of the method which should print out all pants of a specific size:
ListPants(ArrayList<Pants> selection, Pants.SizeType size)
That is correct. Now, your code is looping over all pants and over all possible sizes:
public static void ListPants(ArrayList<Pants> selection, Pants.SizeType size)
{
for (Pants.SizeType sizeType : Pants.SizeType.values()) {
for (Pants pants : selection) {
if (pants.getSize().equals(sizeType)) {
System.out.println(selection.toString());
Since this looks like a homework assignment, i'll phrase my answer as a question:
Where are you using the size parameter in the method body of ListPants?
I am assuming your class cannot implement new interfaces, and not using interfaces at all.
You can use Collections.sort(List,Comparator) with a Comparator, which is built for your class.
Something like
Collections.sort(selection,new Comparator<Pants>() {
#Override
public int compare(Pants p1, Pants p2) {
//implement your compare method in here
...
}
});
If you are eager to create your own sorting algorithm, have a look of this list of sorting algorithms. Simplest to implement (though pretty slow) IMO is selection-sort
I'm using GWT.
When it is compiling the Java code to Javascript code, sometimes it changes some of the members' names.
for example:
private int height;
becomes in the JS:
height_0;
Example:
public class TestClass
{
private int a;
public TestClass()
{
a = 0;
}
public TestClass(int a)
{
this.a = a;
}
public int getMember()
{
return a;
}
public void advance()
{
a++;
}
}
Will result in output like so:
function TestClass_0(){
this.a_0 = 0;
}
function TestClass_1(a){
this.a_0 = a;
}
function TestClass(){
}
_ = TestClass_1.prototype = TestClass_0.prototype = TestClass.prototype = new Object_0;
_.advance_0 = function advance(){
++this.a_0;
}
;
_.getClass$ = function getClass_1(){
return Lcom_autodesk_autocadws_gwt_platform_testExporter_TestClass_2_classLit;
}
;
_.getMember_0 = function getMember(){
return this.a_0;
}
;
_.a_0 = 0;
}
The name of the member a was changed to a_0. In some cases, when using web workers, the code will be compiled differently on the web worker script, and the member's name will not be changed (or will be cjanged to a_1, for example).
My problem with that is when I transfer objects in messages to web workers. When coding the web worker side in Java, I'm expecting to access the member a, and not a_0. Using getters does not solve the issue, since they are simply replaced with direct access when compiled to JS.
My question:
Why are these naming changes occur? In which cases? Is it possible to avoid them?
Thanks a lot.
In most cases, the fields will actually be renamed to something lik a, b, etc. What you're seeing here is due to compiling with -style PRETTY which does not obfuscate the code.
The reason GWT obfuscates the code is to make it smaller.
If you need to pass objects to the outside world, you have to serialize them (or map them to JavaScript objects) to a stable structure.
The easiest way to do it is to use a JavaScriptObject. You can also have a look at gwt-exporter.
We have App A as main app. Now we build from it App B which uses a subset of App A's functionality.
App A stays like it is whereas app B only uses a subset of A
So I want to refactor the function without or with as little dublication as possible and with maximum readability.
So the function looks like this (it is actually longer, this is an excerpt):
class SomeClass {
Data prepareData() {
if (this.bothId==1 || this.appAid=2 /*or only relevant for appA*/) {
if(this.data==null) { /*appA*/
appAdoSmth(); /*appA*/
}
boolean merge=false; /*appA*/
if (this.data==null) { /*appA*/
merge=appAanalyze(data); /*appA*/
}
bothPrepare(merge);
} else if (bothIsRelevant()) {
if(appArelevant()) { /*appA*/
data=appAprepare(); /*appA*/
} else {
data=prepareBoth();
}
bothUpdateSomeValue();
}
}
How would you do it?
Other Answers address the general question of how to refactor code. They offer good advice, but I don't think it is what you are asking.
I think you are asking about possible refactorings of the code in your question.
It is hard to give an answer that is generally applicable, or even specifically applicable. (The sample code isn't your real code, and it is a little difficult to understand what it actually "means").
AndreasD gives one approach: break the big complicated nested if into separate methods.
Another approach is to use the Stragegy design pattern. Separate the code that is specific to each app into strategy classes. For example:
interface Strategy {
Data prepareData();
}
class GeneralStrategy implements Strategy {
Data prepareData() {
// do general preparation
}
}
class App1Strategy extends GeneralStrategy {
Data prepareData() {
// do app1-specific preparation
super.prepareData();
// do more app1-specific preparation
}
}
and so on.
I ideal world develop unit test that validates that existing implementation of your function works.
Then start changing code incrementally and run your test after every change.
It is hard to give your formal recommendation without knowing your code structure. But generally try to find duplicate code fragments, write methods that implement this logic with parameters and replace the duplicate fragments to your new method. Etc, etc.
Good luck.
Readbility can be improved by extracting some logic in separate methods. That is a refactoring method.
Data prepareData() {
if (this.bothId==1 || this.appAid=2 ) {
handleCase1(); // <- you'll find better names for the methods
} else if (bothIsRelevant()) {
handleCase2();
}
}
private void handleCase1() {
if(this.data==null) {
appAdoSmth();
}
boolean merge=false;
if (this.data==null) {
merge=appAanalyze(data);
}
bothPrepare(merge);
}
private handleCase2() {
if(appArelevant()) {
data=appAprepare();
} else {
data=prepareBoth();
}
bothUpdateSomeValue();
}
This doesn't reduce the number of if/else, of course, but it keeps the "main" method simple.
If I were you I would run a coverage report on this class. (e.g. http://ecobertura.johoop.de/ or http://www.eclemma.org/) This way Eclipse can show covered lines green and this helps you to identify the cases. With this aid it's much easier to separate green lines and pull them into methods.
What's the best practice for specifying flags in a Java method?
I've seen SWT using int as bitfields, like:
(example partially from "Effective Java, 2nd Ed." page 159):
public class Text {
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
void printText(String text, int flags) {
}
}
and your client call looks like:
printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);
..but this is discouraged as you can mixed flags (int values) from different classes together without any compiler checks.
In the same book ("Effective Java"), I see the use of EnumSet, but then your user call becomes:
printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));
I find this a bit verbose and I prefer the elegance of SWT.
Is there any other alternative or is this basically the two tastes you must pick?
Guess you have hit a wall. I don't see any other option. Java is verbose that's a fact. In situations like this i usually add a local variable to make the code more readable. You can do this,
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
printText("hello", styles);
If you want bit style flags, Java wraps them in a BitSet. It's been around for ages, yet few people bother to use it (preferring embedding C style bit handling in ints).
The api for BitSet can be found here.
Coupled with a few well chosen static ints, it does pretty well until you start getting into checking and setting multiple bits in one pass.
I advise that you go with the EnumSet approach.
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
This approach provides better type safety, and Style being an enum will have full-blown OO capabilities.
Late answer for anyone coming across this. Here is one way to do it to reduce memory and have a nice enum like api:
public static class MyFlag {
public static final MyFlag A = new MyFlag(1<<0);
public static final MyFlag B = new MyFlag(1<<1);
public static final MyFlag C = new MyFlag(1<<2);
public static final MyFlag ALL = A.and(B).and(C);
private final int flag;
private MyFlag(int flag){
this.flag = flag;
}
public MyFlag and(MyFlag limit){
return new MyFlag(flag & limit.flag);
}
public MyFlag not(MyFlag limit){
return new MyFlag(flag | ~limit.flag);
}
public boolean isSet(MyFlag limit){
if(limit ==null){
return false;
}
return (this.flag & limit.flag) != 0;
}
}
method:
public void doFoo(MyFlag flag){
if(MyFlag.A.isSet(flag)){
....
}
if(MyFlag.C.isSet(flag)){
....
}
}
call:
x.doFoo(MyFlag.A.and(MyFlag.C));
If you only have a limited number of methods that will be taking a set of styles (like printText, in your example), you can tweak their signature to take a variable number of Style params:
void printText(String text, Style... flags) {
EnumSet<Style> style = logicalOr(flags); // see comment below
...
}
And then your calls are very close to the untyped (int) flag route:
printText("hello", Style.BOLD, Style.ITALIC);
Sadly, there is no EnumSet.of(E... ) factory, just EnumSet.of(E first, E... more), so you'll need a generic logicalOr method to split your array into first + rest chunks. Left as an exercise to the reader =).