In Python, I can define two variables with an array in one line.
>>>[a,b] = [1,2]
>>>a
1
>>>b
2
How do I do the same thing in Java?
I have a couple of variables in class PCT which type is final. Is there a way to define them in one line in a Python like fashion? The following format clearly does not work in Java. I could define them separately, but it will call the parseFile method twice which I want to avoid.
public class PCT {
final int start;
final int stop;
public PCT (File file) {
//......
//......
// the following statement does not compile
[start, stop] = parseFile(file);
}
public int[] parseFile(File f) {
int[] aa = new int[2];
// ....
// ....
return aa;
}
}
You can define multiple variables like this :
double a,b,c;
Each variable in one line can also be assigned to specific value too:
double a=3, b=5.2, c=3.5/3.5;
One more aspect is, while you are preparing common type variable in same line then from right assigned variables you can assign variable on left, for instance :
int a = 4, b = a+1, c=b*b;
Noticed, you can also practice arithmetic operations on variable by remaining in the same line.
This is not possible, but you also don't need to call parseFile twice.
Write your code like this:
int [] temp = parseFile(file);
start = temp[0];
stop = temp[1];
Python (I believe) supports multiple return values. Java obeys C conventions, and so doesn't permit it. Since that isn't part of the language, the syntax for it isn't either, meaning slightly gross hacks like the temp array are needed if you're doing multiple returns.
When declaring several variables of the same type, you can do the following:
int a = 1, b = 2, c = 3; //etc.
If you literaly mean line; as long as you place a semicolon in between two statements, they are executed as if there is a new line in between so you can call:
a = 1; b = 2;
You can even compress an entire file into a oneliner, by removing comment (that scope to the end of the line). Spacing (space, tab, new line,...) is in general removed from the Java files (in memory) as first step in the Java compiler.
But you are probably more interested in a singe statement. Sytax like [start, stop] = parseFile(file); is not supported (at least not for now). You can make a onliner:
int[] data = parseFile(file); start = data[0]; stop = data[1];
Maybe this is what you're looking for:
int array[] = {1,2};
Java array assignment (multiple values)
If you're looking to explicitly assign to each element, I don't think you can do that within one assignment, as a similar concept with the 2-d example below. Which seems like what you want as Jeremy's answers specifies.
Explicitly assigning values to a 2D Array?
Maybe
public class PCT
{
final Point pos; // two ints!
public PCT (File file)
{
pos = parseFile(file);
}
public int[] parseFile(File f)
{
Point aa = new Point();
// ....
// ....
return aa;
}
}
Related
Question related to frames of function and effective finality of variables.
int lenMin = list.get(0).length();
for (String s : list)
if (s.length() < lenMin)
lenMin = s.length();
list
.stream()
.filter(s -> lenMin == s.length())
.forEach(System.out::println);
st:1. here we create a variable.
st: 3-5 here we do something with it (change it).
st:9 the lenMin variable is underlined in red.
Effectivity finality we cannot change, but can we use it? I know that the lambda has a new frame, but if we do this:
int len = lenMin;
list
.stream()
.filter(s -> len == s.length())
.forEach(System.out::println);
then there will be no error.
Please explain why this is happening?
Functions that can close over variables need a way to capture those variables.
If a variable can't change, then you can easily capture variables by copying their values.
Java does exactly that. Java lambdas, and inner classes simply correspond to classes that have an extra field for each captured variable.
The JVM only understands flat classes; nested and inner classes are compiler fictions.
Runnable f() {
int answer = 42;
class C extends Runnable {
public void run() { System.out.println(answer); }
}
return new C();
}
compiles to something equivalent to
class C {
private int answer; // Capturing field
C(int answer) { this.answer = answer }
void run() { System.out.println(this.answer); }
}
Runnable f() {
int answer = 42;
return new C(answer);
}
This change is called closure conversion.
As long as answer is only assigned once, javac can do simple closure conversion: copying answer into any classes and lambdas that need it.
But simple copying doesn't work if a local variable might change after being captured.
int answer = 42;
Runnable c = new C();
answer += 1;
c(); // Should this print 42 or 43?
Programmers familiar with languages that allow for reassignment of closed-over variables would get confused if the above didn't behave like the JavaScript below.
let answer = 42;
let c = () => console.log(answer);
answer += 1;
c(); // Logs 43
Java could allow for mutable closed-over variables by doing more complicated closure conversion. For example, instead of copying answer, storing answer in a shared object and rewriting reads&writes to be reads/writes of a property or element of that shared object.
For example,
int[] answerBox = new int[1];
answerBox[0] = 42; // assignment
...
answerBox[0] = 43; // re-assignment
...
System.out.println(answerBox[0]);
...
Java's designers decided not to do that though; capturing by-reference the way JavaScript does would introduce a host of subtle complications. JavaScript is single threaded, but the JVM is not, so imagine when a closed over long variable is suddenly assigned in more than one thread.
This is not hard to work around though as long as you don't need to mutate captured state after creating the capturing value.
Runnable f() {
int x = 1;
x += 1;
return () -> System.out.println(x); // ERROR
}
The above fails, but the below works; we simply store the state of the non-effectively-final x in an effectively final finalX that the lambda can capture.
Runnable f() {
int x = 1;
x += 1;
int finalX = x;
return () -> System.out.println(finalX); // OK
}
So the question is: why one has to introduce a new copy, to have a variable, that is effectively final (= could be made final). Here len.
int len = lenMin;
list
.stream()
.filter(s -> len == s.length())
.forEach(System.out::println);
The reason that the lambda (inside filter) is an anonymous implemented interface instance, that uses len as follows: as it is a local variable, it copies it into a local interface variable with the same name len.
But now one has two variables (though same names). As the lambda theoretically could run in another thread, one has two threads that can change same named variables differently. The language designers did not want to allow two lens with different values, and simply required that the variable is not changed, effectively final.
Here it would not be dangerously misleading, but assume you later assign to len at the end or inside a lambda, and perhaps use .parallelStream(). Then suddenly a compile error must be given at an unchanged piece of code.
That is an additionally sufficient reason to keep the rule simple: a local variable used inside a lambda must be effectively final.
public class Test {
public int [] x;
public Test(int N)
{
int[] x = new int [N];
for (int i=0;i<x.length;i++)
{
x[i]=i;
StdOut.println(x[i]);
}
}
public static void main(String[] args) {
String path = "/Users/alekscooper/Desktop/test.txt";
In reader = new In(path);
int size=reader.readInt();
StdOut.println("Size = "+size);
Test N = new Test(size);
StdOut.println(N.x[3]);
}
/* ADD YOUR CODE HERE */
}
Hello guys. I'm learning Java through reading Robert Sedgwick's book on algorithms and I'm using his libraries such as StdOut, for example. But the question is about Java in general. I don't understand why Java here throws a NullPointerException. I do know what that means in general, but I don't know why it is here because here's what I think I'm doing:
read an integer number from the file - the size of the array
in the class Test. In my test example size=10, so no out-of-bound type of thing happens.
print it.
create the object N of type Test.
In this object I think I create an array of size that I have just
read from the file. For fun I initialize it from 0 to size-1 and
print it. So far so good.
and here where it all begins. Since my class is public and I've run
the constructor I think I have the object N which as an attribute
has the array x with size elements. However, when I'm trying
to address x, for example,
StdOut.println(N.x[3]);
Java throws NullPointerException.
Why so? Please help and thank you very much for your time.
what you did is called shadowing you shadowed your field x with local variable x. so all you need to do is avoiding this:
int[] x = new int [N]; is wrong, if you want your field to initialize instead of a local variable then you could do something like : x = new int [N]; for more information read this
change the first line in constructor from
int[] x = new int [N];
to
x = new int [N];
it should work...
Actually in constructor when you say int[] x, it is creating one more local variable instead setting data to public variable x... if you remove int[] from first line of constructor then it initizes the public variable & you will be able to print them in main() method
Inside public Test(int n):
Change
int[] x = new int [N]; // Creating a local int array x
to
x = new int [N]; // Assigning it to x
Everyone has given the code that would work. But the reason is something called as variable scoping. When you create a variable (by saying int[] x, you are declaring x as an integer array and by saying x = new int[4] you are assigning a new array to x). If you use the same variable name x everywhere and keep assigning things to it, it'll be the same across your class.
But, if you declare int[] x one more time - then you are creating one more variable with the name x - now this can result in duplicate variable error or if you're declaring in a narrower 'scope', you will be overriding your previous declaration of x.
Please read about java variable scopes to understand how scoping works.
int size=reader.readInt(); // size < 3
StdOut.println(N.x[3]); // length of x[] less than 3, so x[3] case NullPointException
This question already has answers here:
Variable used in lambda expression should be final or effectively final
(9 answers)
Closed 4 years ago.
I would like to use local variables in lambda functions but I get error:
Please see the 1. and 2. points in the code.
class Foo {
int d = 0; // 1. It compiles, but ugly, 2. doesnt compile
public void findMax(List<List<Route>> routeLists) {
int d = 0; // 2.Error : Local variable dd defined in an enclosing scope must be final or effectively final
routeLists.forEach(e-> {
e.forEach(ee -> {
d+=ee.getDistance();
});
});
... doing some other operation with d
}
}
How can I use them whitout setting them as global variables ?
forEach is the wrong tool for the job.
int d =
routeLists.stream() // Makes a Stream<List<Route>>
.flatMap(Collection::stream) // Makes a Stream<Route>
.mapToInt(Route::getDistance) // Makes an IntStream of distances
.sum();
Or just use nested for loops:
int d = 0;
for (List<Route> rs : routeLists) {
for (Route r : rs) {
d += r.getDistance();
}
}
You can't use an int as variable because it must be final to be used in a stream.
But You can create a class wrapping the int.
Then declare the variable holding this class as final.
Changing the content of the inner int variable.
public void findMax(List<List<Route>> routeLists) {
final IntWrapper dWrapper = new IntWrapper();
routeLists.forEach(e-> {
e.forEach(ee -> {
dWrapper.value += ee.getDistance();
});
});
int d = dWrapper.value;
... doing some other operation with d
}
public class IntWrapper {
public int value;
}
Having side effects is discouraged (or even forbidden?) in the functions used in a stream.
A better way would be one of
routeLists.stream()
.flatMapToInt(innerList -> innerList.stream()
.mapToInt(Route::getDistance))
.sum()
or
routeLists.stream()
.mapToInt(innerList -> innerList.stream()
.mapToInt(Route::getDistance).sum())
.sum()
The first will, for each sublist, create a stream of distances. All these streams will become flattened and summed at once.
The second will create the sum of each sublist and then add all those sums together again.
They should be equivalent, but I am not sure if the one or other is better in terms of performance (i. e., if flattening the streams is more expensive than summing).
A third alternative of flattening the lists and then getting and summing the distances is covered by Andy Turner's answer.
public class Test {
public int [] x;
public Test(int N)
{
int[] x = new int [N];
for (int i=0;i<x.length;i++)
{
x[i]=i;
StdOut.println(x[i]);
}
}
public static void main(String[] args) {
String path = "/Users/alekscooper/Desktop/test.txt";
In reader = new In(path);
int size=reader.readInt();
StdOut.println("Size = "+size);
Test N = new Test(size);
StdOut.println(N.x[3]);
}
/* ADD YOUR CODE HERE */
}
Hello guys. I'm learning Java through reading Robert Sedgwick's book on algorithms and I'm using his libraries such as StdOut, for example. But the question is about Java in general. I don't understand why Java here throws a NullPointerException. I do know what that means in general, but I don't know why it is here because here's what I think I'm doing:
read an integer number from the file - the size of the array
in the class Test. In my test example size=10, so no out-of-bound type of thing happens.
print it.
create the object N of type Test.
In this object I think I create an array of size that I have just
read from the file. For fun I initialize it from 0 to size-1 and
print it. So far so good.
and here where it all begins. Since my class is public and I've run
the constructor I think I have the object N which as an attribute
has the array x with size elements. However, when I'm trying
to address x, for example,
StdOut.println(N.x[3]);
Java throws NullPointerException.
Why so? Please help and thank you very much for your time.
what you did is called shadowing you shadowed your field x with local variable x. so all you need to do is avoiding this:
int[] x = new int [N]; is wrong, if you want your field to initialize instead of a local variable then you could do something like : x = new int [N]; for more information read this
change the first line in constructor from
int[] x = new int [N];
to
x = new int [N];
it should work...
Actually in constructor when you say int[] x, it is creating one more local variable instead setting data to public variable x... if you remove int[] from first line of constructor then it initizes the public variable & you will be able to print them in main() method
Inside public Test(int n):
Change
int[] x = new int [N]; // Creating a local int array x
to
x = new int [N]; // Assigning it to x
Everyone has given the code that would work. But the reason is something called as variable scoping. When you create a variable (by saying int[] x, you are declaring x as an integer array and by saying x = new int[4] you are assigning a new array to x). If you use the same variable name x everywhere and keep assigning things to it, it'll be the same across your class.
But, if you declare int[] x one more time - then you are creating one more variable with the name x - now this can result in duplicate variable error or if you're declaring in a narrower 'scope', you will be overriding your previous declaration of x.
Please read about java variable scopes to understand how scoping works.
int size=reader.readInt(); // size < 3
StdOut.println(N.x[3]); // length of x[] less than 3, so x[3] case NullPointException
This question already has answers here:
How to write a basic swap function in Java [duplicate]
(19 answers)
Java method to swap primitives
(8 answers)
Closed 6 years ago.
Here is the question: write a method that swaps two variables. These two variables should be primitives. It doesn't need to be generic e.g. two int variables. Is there a way?!
While it is not possible to write a function that simply swaps two variables, it is possible to write a helper function that allows you to:
Swap two variables using only one statement
Without temporary variables in the caller's code
Without 'boxing' primitives
With a few overloads (one of them using generics), it works for any type
That's how you could do it:
int returnFirst(int x, int y) {
return x;
}
<T> T returnFirst(T x, T y) {
return x;
}
// other overloads as needed
int a = 8, b = 3;
a = returnFirst(b, b = a); // try reading this as a = b; b = a;
System.out.println("a: " + a + ", b: " + b); // prints a: 3, b: 8
This works because the Java language guarantees (Java Language Specification, Java SE 7 Edition, section 15.12.4.2) that all arguments are evaluated from left to right (unlike some other languages, where the order of evaluation is undefined), so the execution order is:
The original value of b is evaluated in order to be passed as the first argument to the function
The expression b = a is evaluated, and the result (the new value of b) is passed as the second argument to the function
The function executes, returning the original value of b and ignoring its new value
You assign the result to a
If returnFirst is too long, you can choose a shorter name to make code more compact (e.g. a = sw(b, b = a)).
Suppose you need to swap many variables of different types one after the other. By using returnFirst there's no need for intAux, objAux, etc. There's less risk of mistakenly using the wrong variable somewhere, because there are no extra variables (in the caller, at least).
Without using an array or objects, no, it is not possible to do it within a method.
Check out this JavaWorld article that explains it in detail:
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
A swap of two primitives will never work because primitives are passed by value in Java. You can't even write a method to swap two objects for that matter.
Like #Thomas said, the only thing you could do is have your primitives contained within other objects/arrays and modify those.
One-liner for any primitive numbers:
a += (b - (b = a));
You can make a generic version of #marcus's swap method that swaps any number of objects of the same type:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
b = swap(a, a=b);
z = swap(x, x=y, y=z);
In java5, the closest I can think of, which may help you, is :
The AtomicInteger class (and others) have getAndSet() atomic methods ..
To write a swap method that swaps primitives you'd have to have the concept of "out" variables, i.e. variables whose values are passed up to the calling context. C# has those but you must still specify that they're out variables.
This function will swap two ints
Integer[] swap(int a, int b){
return new Integer[]{b,a};
}
Here's a method that swaps two primitive variables
private void swap(){
int a = 1;
int b = 2;
int temp = a;
a = b;
b = temp;
}
It might not be of much use though ;)
Ok seriously, it could be done if the variables are class level:
public class MyClass{
// excuse horrible coding practice of public mutable fields
public int a = 1;
public int b = 2;
public void swap(){
int temp = a;
a = b;
b = temp;
}
}
Again though, I fail to see what the use of this could be
I have read the above answers seeking an explanation as to why it is said that a swapping program cannot be written in java in the way it is written in c++.
I did the following way
program screenshot
As Thomas Owens said. You could probably do it in C by passing variables by &reference, but afaik not in Java without using objects.
Yes it is possible to swap two variable using a method.
But you should declare that method with empty parentheses and then call it by
reference(empty parentheses) .
Here is an example that illustrates swapping of two variable using a method.
public class Swapping
{
static String A="Apple";
static String B="Bat";
public static void swap()
{
String k;
k=A;
A=B;
B=k;
}
public static void main(String[] args)
{
System.out.println("Before swapping");
System.out.println("A= "+A);
System.out.println("B= "+B);
swap();
System.out.println("After swapping");
System.out.println("A= "+A);
System.out.println("B= "+B);
}
}
By compiling the above code the output comes as follows:
Before swapping
A= Apple
B= Bat
After swapping
A= Bat
B= Apple
//In case of call by reference original value is changed if we made changes in the called method
public class Swap
{
public static void main (String[]args)
{
int y = 5;
int x = 4;
int c;
System.out.println("y = "+y);
System.out.println("x = "+x);
c=x; //c = 4
x=y; //x = 5;
y=c;
System.out.println("\n");
System.out.println("y= "+y);
System.out.println("x= "+x);
}
}