In python you can do this:
def f():
return 1, 2, 3
(foo, bar, baz) = f()
Is there an equivalent in java?
tl;dr: No, there isn't such a thing in Java.
You can assign initial values to variables like this:
int foo = 1, bar = 2;
But if your want (1, 2, 3) to be the result of a method call, this is not possible in Java. Java does not allow returning multiple values.
Python allows this:
def foo():
return 1, 2, 3
a, b, c = foo()
The main point, why this does not work in Java is, that the left hand side (LHS) of the assignment must be one variable:
Wrapper wrapper = WrapperGenrator.generateWrapper();
You can not assign to a tuple on the LHS as you can in Python.
If you want (1,2,3) to be the result of a method call, you can use an array:
int[] arr = {1,2,3};
I realize this is an old post, but I could point out a way that comes somewhat close to this.
Using the OP's example (This could obviously use multiple types instead of three ints, but I'm going with the original example),
class Trip{ int foo;int bar;int baz;} // After building this class, have your editor create a constructor for you!
public Trip() {
return new Trip(1,2,3);
}
Trip t = f()
Now at this point I realize you haven't actually ASSIGNED this to three local variables (or member variables) as you would have liked, however you do have a local variable you can use as though you had... like:
t.foo * t.bar + t.baz;
The advantages here are that this is quite terse, hardly more work than the python example and safer/clearer/easier to read; as is I'd be really happy with this!
Perhaps more important though is that as you go on you will realize that this mini-class should have been a real class all along since the values are going to be somewhat associated since they are from the same function!
You can change what you have to a real class with simple editor refactors--replace member access with getter/setter, make members private, extract the class into it's own file and you have a full class!
Chances are that you'll eventually figure out that your original function f() should have been a member (or constructor) of this class in the first place!
By the way, the disadvantage is that this will fully trigger some Java programmers that don't understand that rules were meant to be broken--if you have old coders who are insistent on stuff that seems pedantic (rule-obsessed) it's best not to try this because it'll make their head explode (all over you, most likely).
As I noted in this other question, if your goal is specifically to return multiple values from a function, in Java 16+ you can accomplish something similar to this using a record type:
record FooResult(int a, int b, int c) { }
FooResult produceFoo() {
return new FooResult(1, 2, 3);
}
/* ... */
var f = produceFoo();
System.out.println(f.a + "," + f.b + "," + f.c);
This will let you return any set of types, with named fields, at the expense of having to add a line to declare the record. This won't really help with assignments like (i, j) = (j, i) however.
Related
So suppose my application does lots of repetitive work, for example let's say my application checks lots of various Lists if they're empty or not. There are two methods by which I can accomplish this functionality - (there maybe other methods but since my goal is to understand the difference of the two methods and not the functionality itself here we go)
Method 1 - Tradition Method
public boolean isEmptyOrNull(List list)
{
return list != null && !list.isEmpty();
}
Method 2 - Lambda Way
Assuming we have created a functional interface with class name Demo and boolean isEmptyOrNull as the function.
Demo var = list -> list != null && !list.isEmpty();
So each time I wish to check a list I can either use Method 1 or 2 by using isEmptyOrNull(myList) or var.isEmptyOrNull(myList) respectively.
My question is why should I use Method 1 and not Method 2 and vice versa. Is there some performance aspect or some other aspect as to why I should prefer one method over the other !?
Oof, where to start.
Your idea of what null is, is broken.
isEmptyOrNull is a code smell. You shouldn't have this method.
null is a stand-in value that necessarily can mean 'not initialised', because that's built into java itself: Any field that you don't explicitly set will be null. However, it is very common in APIs, even in java.* APIs, that null can also mean 'not found' (such as when you call map.get(someKeyNotInTheMap)), and sometimes also 'irrelevant in this context', such as asking a bootstrapped class for its ClassLoader.
It does not, as a rule, mean 'empty'. That's because there is a perfectly fine non-null value that does a perfect job representing empty. For strings, "" is the empty string, so use that, don't arbitrarily return null instead. For lists, an empty list (as easy to make as List.of()) is what you should be using for empty lists.
Assuming that null semantically means the exact same thing as List.of() is either unneccessary (the source of that list wouldn't be returning null in the first place, thus making that null check unneccessary) or worse, will hide errors: You erroneously interpret 'uninitialized' as 'empty', which is a fine way to have a bug and to have that result your app doing nothing, making it very hard to find the bug. It's much better if a bug loudly announces its presence and does so by pointing exactly at the place in your code where the bug exists, which is why you want an exception instead of a 'do nothing, silently, when that is incorrect' style bug.
Your lambda code does not compile
Unless Demo is a functional interface that has the method boolean isEmptyOrNull(List list);, that is.
The difference
The crucial difference is that a lambda represents a method that you can reference. You can pass the lambda itself around as a parameter.
For example, java.util.TreeSet is an implementation of set that stores all elements you put inside in sorted order by using a tree. It's like building a phonebook: To put "Ms. Bernstein" into the phonebook, you open the book to the middle, check the name there, and if it's 'above' 'Bernstein', look at the middle of the first half. Keep going until you find the place where Bernstein should be inserted; even in a phonebook of a million numbers, this only takes about 20 steps, which is why TreeSet is fast even if you put tons of stuff in there.
The one thing TreeSet needs to do its job is a comparison function: "Given the name 'Maidstone' and 'Bernstein', which one should be listed later in the phone book"? That's all. If you have that function then TreeSet can do its job regardless of the kind of object you store in it.
So let's say you want to make a phone book that first sorts on the length of names, and only then alphabetically.
This requires that you pass the function that decrees which of two names is 'after' the other. Lambdas make this easy:
Comparator<String> decider = (a, b) -> {
if (a.length() < b.length()) return -1;
if (a.length() > b.length()) return +1;
return a.compareTo(b);
};
SortedSet<String> phonebook = new TreeSet<>(decider);
Now try to write this without using lambdas. You won't be able to, as you can't use method names like this. This doesn't work:
public void decider(String a, String b) {
if (a.length() < b.length()) return -1;
if (a.length() > b.length()) return +1;
return a.compareTo(b);
}
public SortedSet<String> makeLengthBook() {
return new TreeSet<String>(decider);
}
There are many reasons that doesn't work, but from a language design point of view: Because in java you can have a method named decider, and also a local variable named decider. You can write this::decider which would work - that's just syntax sugar for (a, b) -> this.decider(a, b); and you should by all means use that where possible.
There is no advantage in your example. Lamdas are often used in Object Streams, e.g for mapping or filtering by defining "adhoc functions" (that's what lambdas are).
Example: You have a list of strings named allStrings that you want to filter
List<String> longStrings = allStrings.stream()
.filter(s -> s.length() > 5) // only keep strings longer than 5
.collect(Collectors.toList()); // collect stream in a new list
Lambdas were added to introduce functional programming in java. It could be used as a shorthand for implementing single method interfaces (Functional interfaces). In the above example you provided, there is no much advantage. But lambdas could be useful in the below scenario:
Before lambdas
public Interface Calc{
int doCalc(int a, int b);
}
public class MyClass{
public void main(String[] args){
Calc x = new Calc() {
#Override
public int doCalc(int a, int b) {
return a + b;
}
};
System.out.println(x.doCalc(2, 3));
}
}
But with lambdas this could be simplified to
public class MyClass{
public void main(String[] args){
BiFunction<Integer, Integer, Integer> doCalc= (a, b) -> a + b;
System.out.println(doCalc.apply(2, 3));
}
}
This is especially helpful for implementing event listeners (in Android), in which case there are a lot of interfaces provided as part of the API with methods like onClick etc. In such cases lambdas could be useful to reduce the code.
Also with Java 8, streams were introduced and lambdas could be passed to filter/map the stream elements. Stream allow more readable code than traditional for loop / if-else in most cases.
This question is probably as old as the hills. Nevertheless, after reading lots of articles and forums I still don't see a good solution to my problem.
I have to transfer some Monte Carlo simulation programs from C++ to Java. The problem is that it heavily relies on passing variables by reference in functions, like:
void make_step(int &a, int &b, double &c) {
a++;
b += a;
c *= 1.1;
}
There is no passing by reference in Java, as well as possible analogs, like multiple return values or nested functions. Solutions, which I have read on this site, usually involve encapsulation of primitive types into objects. Alternatively - break functions to single-return ones. However, in my case it results in too long and complicated code (few lines of C++ code grow to almost pages in Java). Also, since these algorithms are hard to debug, I want to avoid dramatical changes in code while porting.
What I do now is substituting of all primitive type variables with arrays of length 1 (which are objects and can be modified inside functions). But it doesn't look like very elegant solutions. Does anyone have better ideas?
If you want the parameters to be "in-out" variables, they have to be object references.
With Mutable Wrappers
You can use mutable wrappers but this will require you to slightly modify your existing code (the algorithm):
class Int {
int v;
}
class MDouble {
double v;
}
void make_step(Int a, Int b, MDouble c) {
a.v++;
b.v += a.v;
c.v *= 1.1;
}
With Local Variable Copies
If you want to keep your original code, you can create local variable copies of the wrapped parameters, and you can use those without having to modify your code.
At the end of your method (before return) copy back the local variables into the wrappers and you're done. A tip for this is to use a try-finally block so your local variables will get copied back into the wrappers no matter how or where your method returns:
void make_step(int[] aa, int[] bb, double[] cc) {
int a = aa[0];
int b = bb[0];
double c = cc[0];
try {
// all your original code comes here
a++;
b += a;
c *= 1.1;
} finally {
aa[0] = a;
bb[0] = b;
cc[0] = c;
}
}
There are few options:
Wrap all parameters in an object. The simple version indeed makes the program longer, but if you can wrap the entire algorithm in an object then those parameters become the object members.
Use mutable integers (objects) - either Java's AtomicInteger which has get()/set() methods, or the commnos-lang version
There are mutable Integer and Decimal classes out there you can use those to pass by reference. Check out Apache Commons libraries here
When writing same logic from c++ to java
Rely more on .equals and comparators over == >< for comparisions
Use member variables and for local variable return the updated objects back to the called methods to get the changes.
You can use "atomic references" to wrap your object in a reference.
There are atomicXXX classes for most basic types as well. These will work similarly to normal references aside from the overhead of creating them in the first place.
Arrays of length 1 are just as a solution, but if you dislike the syntax or appearance of them, this is the only other solution that I know of that can mimic the same behavior without a general refactor.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why there is no way to pass by reference in java
Can anybody tell me why exactly Java does not provide C# "out" type feature when dealing with method parameters to pass by reference ?
I mean why would not it allow us to pass primitive data types like boolean for example, pass by reference. I have tried also with wrapper class java.lang.Boolean but still to no avail. It still wont allow me to pass variable by reference.
Is there any specific reason why Java still has not provided us with this even in version 7 ?
Java only has pass by value. This was a decision made when the language was designed.
Why doesn't java support pass by reference like C++
There is exactly one parameter passing mode -- pass by value -- and that helps keep things simple.
-- James Gosling, et al., The Java Programming Language, 4th Edition
If you want you can put your boolean as a member inside a mutable class (you can't use Boolean because it is immutable), and pass a reference to that class. Apache Commons even has a class called MutableBoolean that you can use.
Only the language design team could tell you why, but I believe the reason for not allowing "out" parameters might be something like: If you want a method that calculates two things, what you really want is either two methods, or one method that returns an object. This supposedly leads to better design and more maintainable code.
Note that you if you really want "out parameters" you can easily use arrays of one element. For example:
void div(int a, int b, int[] q, int[] r) {
if (q != null) q[0] = a/b;
if (r != null) r[0] = a%b;
}
// elsewhere:
int[] quotient = new int[1];
int[] remainder = new int[1];
div(4, 3, quotient, remainder);
This is just my opinion but I feel that the designers of Java believed they could simplify programming by eliminating features rather than making them more intuitive and easier to handle.
Short answer is that it's a design decision and there's nothing you can do with passing by reference that you couldn't do with passing object references by value.
As for your particular problem, there are two solutions:
A mutable wrapper class:
final class BooleanRef {
public boolean value;
}
And use it as:
// Function
void changeTheBoolean( BooleanRef b ){
b.value = true;
}
// Call:
BooleanRef b = new BooleanRef();
changeTheBoolean( b );
OR, (more hackish but more lightweight) wrap in an array:
// Function
void changeTheBoolean( boolean[] b ){
b[0] = true;
}
// Call:
boolean[] b = new boolean[1];
changeTheBoolean( b );
I am trying to learn a java-based program, but I am pretty new to java. I am quite confusing on the following two lines of java code. I think my confusion comes from the concepts including “class” and “cast”, but just do not know how to analyze.
For this one
XValidatingObjectCorpus<Classified<CharSequence>> corpus
= new XValidatingObjectCorpus<Classified<CharSequence>>(numFolds);
What is <Classified<CharSequence>> used for in terms of Java programming? How to understand its relationships with XValidatingObjectCorpusand corpus
For the second one
LogisticRegressionClassifier<CharSequence> classifier
= LogisticRegressionClassifier.<CharSequence>train(para1, para2, para3)
How to understand the right side of LogisticRegressionClassifier.<CharSequence>train? What is the difference between LogisticRegressionClassifier.<CharSequence>train and LogisticRegressionClassifier<CharSequence> classifier
?
These are called generics. They tell Java to make an instance of the outer class - either XValidatingObjectCorpus or LogisticRegressionClassifier - using the type of the inner object.
Normally, these are used for lists and arrays, such as ArrayList or HashMap.
What is the relationship between XValidatingObjectCorpus and corpus?
corpus is just a name given to the new XValidatingObjectCorpus object that you make with that statement (hence the = new... part).
What does LogisticRegressionClassifier.<CharSequence>train mean?
I have no idea, really. I suggest looking at the API for that (I think this is the right class).
What is the difference between LogisticRegressionClassifier.<CharSequence>train and LogisticRegressionClassifier<CharSequence> classifier?
You can't really compare these two. The one on the left of the = is the object identifier, and the one on the right is the allocator (probably the wrong word, but it is what it does, kind of).
Together, the two define an instance of LogisticRegressionClassifier, saying to create that type of object, call it classifier, and then give it the value returned by the train() method. Again, look at the API to understand it more.
By the way, these look like wretched examples to be learning Java with. Start with something simple, or at least an easier part of the code. It looks like someone had way too much fun with long names (the API has even longer names). Seriously though, I only just got to fully understanding this, and Java was my main language for quite a while (It gets really confusing when you try and do simple things). Anyways, good luck!
public class Sample<T> { // T implies Generic implementation, T can be substituted with any object.
static <T> Sample<T> train(int par1, int par2, int par3){
return new Sample<T>(); // you are calling the Generic method to return Sample object which works with a particular type of generic object, may it be an Integer or a CharSequence. --> see the main method.
}
public static void main(String ... a)
{
int par1 = 0, par2 = 0, par3 = 1;
// Here you are returning Sample object which works with a sequence of characters.
Sample<CharSequence> sample = Sample.<CharSequence>train(par1, par2, par3);
// Here you are returning Sample object which works with Integer values.
Sample<CharSequence> sample1 = Sample.<Integer>train(par1, par2, par3);
}
}
<Classified<CharSequence>> is a generic parameter.
LogisticRegressionClassifier<CharSequence> is a generic type.
LogisticRegresstionClassifier.<CharSequence>train is a generic method.
Java Generics Tutorial
I have really stuck on two Java related issues. One simple and one more difficult.
Regarding the creation of a 2D array, I initialize a table like this:
private String [][] table_of_classifiers = null;
and then, within a function, I fill its contents like this:
String [][] table_of_classifiers = {
{"x1","x","x","x","x"},
{"x2","x","x","x","x"},
{"x3","x","x","x","x"},
{"x4","x","x","x","x"},
{"x5","x","x","x","x"},
{"x6","x","x","x","x"},
};
But as you can guess the second table overwrites (locally) the first one, that is of course not what I want to do. What I do wrong? Note that the dimension of the table is not known from the beginning.
Regarding the creation of a 2D array, I initialize a table like this:
private String [][] table_of_classifiers = null;
Not really. This is the declaration and initialization of a variable that can point to a "2d array", "table" or more exact an "array of arrays" of Strings.
Unless you work with that fact that the variable can/will be null, initializing it to null is usually a bad idea, because you need to do extra work to check for null. Examples:
String[][] a;
// ...
String b = a[0][0];
This won't compile, unless a wasn't initialized in the mean time. This is a good thing, because you can avoid a potential bug.
String[][] a = null;
// ...
String b = a[0][0];
This will however will compile, and if you forgot to actually assign the variable a real array, the program will "crash" with a "null pointer exception" or you need to add additional code/work to check for null.
I fill its contents like this:
String [][] table_of_classifiers = {
{"x1","x","x","x","x"},
{"x2","x","x","x","x"},
{"x3","x","x","x","x"},
{"x4","x","x","x","x"},
{"x5","x","x","x","x"},
{"x6","x","x","x","x"},
};
You are not "filling" anything here. For something to be filled it must exist first, but you haven't created anything yet.
Here you are declaring a second variable of the same name, which is only possible if you are in a different scope that the first one, and in that case you are "hiding" ("shadowing") the original variable if it originally was accessible from this new scope.
But as you can guess the second table overwrites (locally) the first
one, that is of course not what I want to do. What I do wrong?
Which "first" table? There was no first table until now, only a first variable. The others have shown you what you need to do to assign the "table" to the original variable, by not using the "declaration" String[][] at the beginning of the line.
Otherwise it's impossible to say what you are "doing wrong" because you haven't really explained what you are attempting to do.
Note that the dimension of the table is not known from the beginning.
It's not? How/why are you using a array literal then? Literal arrays are for creating arrays of a fixed size with a fixed "prefilling".
What exactly do mean with "the beginning"? Isn't the size known when you are programming (during compile time) or when the program starts (at run time)?
If you get the size of the array during run time you can create a normal array with new:
int a = ...;
int b = ...; // Get the sizes from somewhere, e.g, user input
String[][] table_of_classifiers = new String[a][b];
// Now you have an "empty" table
If size "changes" during run time, then - depending on what you are actually attempting to do - then an array is the wrong tool and you should be using a List implementation such as ArrayList instead.
Regarding "eval", as the others say, Java is a compiled language making "eval" basically impossible. The is "reflection" or the use of Class types to achieve what you are hinting at, but you really need to explain much more extensively what you are trying to achieve, then it may be possible to help you here.
However reflection and CLass types are a complicated matter, and considering you are obviously struggling with the most basic Java concepts, you have a long way to go to until you will be able to do what you want to do.
Just do:
class Foo {
private String [][] table_of_classifiers = null;
void bar() {
table_of_classifiers = new String[][] {
{"x1","x","x","x","x"},
{"x2","x","x","x","x"},
{"x3","x","x","x","x"},
{"x4","x","x","x","x"},
{"x5","x","x","x","x"},
{"x6","x","x","x","x"},
};
}
}
Java doesn't have eval (because it's a compiled language), but it does have reflection. It's almost certainly not the best approach to whatever it is that you want to do, though.
Regarding your first problem: to assign to table_of_classifiers without redeclaring it, write:
table_of_classifiers = new String[][] {
{"x1","x","x","x","x"},
{"x2","x","x","x","x"},
{"x3","x","x","x","x"},
{"x4","x","x","x","x"},
{"x5","x","x","x","x"},
{"x6","x","x","x","x"},
};
Regarding eval . . . the problem is that the run-time doesn't have the names of scoped local variables, and although it can get the names of instance variables, it has to do that within the context of an object. It's possible to address these sorts of issues, but it's non-trivial, and will involve major compromises. I think you have to thoroughly understand how scoping works and how reflection works before you start figuring out what features eval will support, because otherwise you'll just be disappointed at all the requirements you give it that turn out to be impossible.