Divide every element in 2 dimensional array - java

I have the sums of x and y coordinates and I need to calculate the mean
float [][] sums = new float[n][2];
e.g. my array consists of:
{ [ 8,6 ],
[ 4,2 ] }
After the dividing to 2:
{ [ 4,3 ],
[ 2,1 ] }
I can do this with loops but I wonder if It is possible to do it with 1 function.

You can simply encapsulate your for loops into a function and call it:
import java.util.Arrays;
void setup(){
float [][] sums = new float[][]{ { 8,6 },
{ 4,2 } };
print("pre: ");
System.out.println(Arrays.deepToString(sums));
matMul(sums,0.5);
print("post:");
System.out.println(Arrays.deepToString(sums));
}
void matMul(float[][] data,float multiplier){
for(int y = 0; y < data.length; y++){
for(int x = 0; x < data[y].length; x++){
data[x][y] *= multiplier;
}
}
}
Here are a few pointers if you're just getting started with functions.
The simplest thing a function can do is encapsulate a bunch of instructions, but
no allow any data from outside the function to be read and not return any data out.
Here is a very simple/boring example:
void sayHello(){
println("hello");
}
The point of is it to get familiar with the syntax.
A function has:
a (return) type: if the function returns any result, what kind of result is it ? (a number, a string of text, an Object, etc.), if not it's simply void
a name (so we can call it)
arguments (0 or more) within parenthesis, each having a type and name (similar to a local variable)
a body delinieated by the { and } symbols: this everything defined within this block is only visible to this block (except what's returned, if anything). This is known as the scope of the function
You've probably already defined functions that don't return results: void setup(){}, void draw(){}
You've probavly already called functions before: used the name and arguments (if any) in paranthesis (e.g. println("hi");, point(50,50);, noCursor();, etc.)
Here's a simple example of a function that takes two inputs and returns one output: the sum of the inputs:
int sum(int a, int b){
return a+b;
}
Instead of void we return a result of int type and the arguments are a couple of integers named a and b. The only other extra thing is the return keyword used to (you guessed it) return the result (and exit the function block).
Here a basic example calling the function:
void setup(){
println(add(2,2));
println(add(4,4));
}
int add(int a, int b){
return a + b;
}
If you want to read more on it check out Kevin Workman's Creating Functions Processing Tutorial
Bare in mind the the void method transforms the array reference to pass as an argument to the function. There may be situations where you don't want to change the input data, yet return the result. In such as case you can either copy the array beforehand and pass a copy, or have a version of the function that makes a copy for you:
import java.util.Arrays;
void setup(){
float [][] sums = new float[][]{ { 8,6 },
{ 4,2 } };
print("sums: ");
System.out.println(Arrays.deepToString(sums));
float[][] result = matMul(sums,0.5);
print("result: ");
System.out.println(Arrays.deepToString(result));
print("original:");
System.out.println(Arrays.deepToString(sums));
}
float[][] matMul(float[][] data,float multiplier){
// check input data
if(data == null || data.length == 0){
println("no data to multiply, returning null");
return null;
}
// make another array of the same shape
float[][] result = new float[data.length][data[0].length];
// do the multiplcation, storing the result into the duplicate array
for(int y = 0; y < data.length; y++){
for(int x = 0; x < data[y].length; x++){
result[x][y] = data[x][y] * multiplier;
}
}
// return the result
return result;
}
Notice a few checks at the start of the function: in general it's a good idea to validata data coming in, just in case, and display a message that will make it easy to fix the issue (withouth spending to much figuring out what the error means).

Something like this:
Arrays.stream(sums).map(y -> Arrays.stream(y).map(x -> x/2).toArray(Double[]::new))
.toArray(Double[][]::new);
probably should do what you want.

Related

How to replace the overridden methods with a Recursive implementation

I want to use recursion in order to collapse the overridden add() methods in the code and allow the user to provide any number of terms.
I've made a couple of changes to my code, but I'm not getting the desired result.
Examples of user input and expected output.
Output (for input 3 + 4)
7.0
Output (for input 3 + 4 + 5)
12.0
The code I have:
import java.util.*;
public class Recursion {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
String exp = input.nextLine();
System.out.println(solver(exp.split(" ")));
}
public static double solver(String[] expression) {
double result = 0;
if (expression.length == 3) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]));
}
else if (expression.length == 5) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]));
}
else if (expression.length == 7) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]));
}
else if (expression.length == 9) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]),
Double.parseDouble(expression[8]));
}
else if (expression.length == 11) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]),
Double.parseDouble(expression[8]), Double.parseDouble(expression[10]));
}
return result;
}
public static double add(double a, double b) {return a + b;}
public static double add(double a, double b, double c) {return a + b + c;}
public static double add(double a, double b, double c, double d) {return a + b + c + d;}
public static double add(double a, double b, double c, double d, double e) {return a + b + c + d + e;}
public static double add(double a, double b, double c, double d, double e, double f) {return a + b + c + d + e + f;}
}
That's doable with recursion.
But before diving into recursive implementation, it's worth to find out how to solve this problem iteratively because it'll give you a better understanding of what the recursion does.
Firstly, I want to point out at issues with the code you've provided.
Your existing solution is brittle since it depends on the consistency of the user input, and it will fail because of the single additional white space or if a white space will be missing.
Another draw-back is that you have a lot of methods and with them, you are able to handle only a limited number of arguments in the given expression. Let's fix it.
Since your code is intended to perform the arithmetical addition, I think it'll be better to split the input on the plus symbol + and give a user a bit of freedom with white spaces.
For that, we need to pass the following regular expression into the split() method:
"\\s*\\+\\s*"
\s* - implies 0 or more white spaces;
\+ - plus symbol has a special meaning in regular expressions and needs to be escaped with a back-slash.
And since there's more than one arithmetical operation (and you also might want to implement others letter on). It's better to extract your the logic for splitting the user input into a separate method:
public static double add(String expression) {
return addIteratively(expression.split("\\s*\\+\\s*"));
}
expression.split() will return an array of numeric strings that will allow to substitute all your methods with a single method that expects a string array String[] or varargs String... expression (which will allow you to pass as an argument either an array of strings or arbitrary number of string values).
public static double addIteratively(String[] operands) {
double result = 0;
for (String next: operands) {
result += Double.parseDouble(next);
}
return result;
}
Now, when it's clear how to deal with this task iteratively (remember every problem and could be addressed using iteration is also eligible for recursion and vice versa) let's proceed with a quick recap on recursion.
Every recursive method consists of two parts:
Base case - that represents a simple edge-case (condition when recursion terminates) for which the outcome is known in advance.
Recursive case - a part of a solution where recursive calls are made and where the main logic resides.
To process the given array recursively, we can track the position in the array by passing it with each method call.
The base case will represent a situation when there's no more elements left in the array, i.e. current position is equal to the array's length. Since there's no element under the given position, the return is 0.
In the recursive case we need to parse the number under the current position and add the result of the recursive call with position incremented by 1 to it. That will give us the return value.
The recursive implementation might look that:
public static double addAsDouble(String[] operands, int pos) {
if (pos == operands.length) { // base case
return 0;
}
// recursive case
return Double.parseDouble(operands[pos]) + addAsDouble(operands, pos + 1);
}
Method responsible for splitting the user input.
public static double add(String expression) {
return addAsDouble(expression.split("\\s*\\+\\s*"), 0); // recursion starts at position 0
}
main() - here, you just need to call the add() providing a string inter by the user and bother of what is happening inside add. That makes code cleaner and easier to read.
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
String exp = input.nextLine();
System.out.println(add(exp));
}
Output
3 + 4 +5
12.0
You are not passing the correct indexes to the various add methods. For example, if you want to add three numbers, you should do the following:
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[1]), Double.parseDouble(expression[2]));

Android/Java using two dimensional array to create chatbot

public class ChatBot {
String[][] chatBot={
// standard greetings
{ "hi", "hello", "hey" }, { "hi user"},
// question greetings
{ "how are you" }, { "good"},
// default
{ "I did not understand. Please try something else" }, };
public ChatBot() {
}
public String checkAnswer(String message) {
byte response = 0;
int messageType = 0;
String x = null;
List temp;
int cblength = chatBot.length - 1;
while (response == 0 && messageType <= cblength) {
temp = Arrays.asList(chatBot[messageType]);
if (temp.contains(message)) {
response = 2;
x = chatBot[(messageType) + 1][0];
}
messageType = messageType + 2;
if (response == 1)
x = chatBot[chatBot.length - 1][0];
}
}
return x;
}
I created this simple chatbot to test my chat application. It uses a two dimensional String Array to save the possible inputs and outputs. The checkAnwer method receives the user input and is supposed to return the correct output. It uses a while loop to check the input fields and return the corresponding output, if the content of the field matches with the array. If the loop reaches the end of the array, it is supposed to return the default answer. The first group of inputs (hi/hello/hey) returns the right output(hi user), but every other input causes the while-loop to exceed the array length.
Edit
I removed the error in the Code, all inputs are now accepted, non valid inputs return null.
Edit2
I changed int cblength = chatBot.length - 1;
to
int cblength = chatBot.length;
and messageType = messageType + 2;
to
if ((messageType+2)>=cblength)
{
response=1;
}
else {
messageType = messageType + 2;
}
The code is now working properly.
If I'm understanding your code correctly, chatBot has a length of 5. On each full pass of the while loop, messageType is incrementing by 2. This means that on the second pass, messageType = 2. This means that on the following line :
x = chatBot[(messageType * 2) + 1][0];
We are looking for (2*2)+1 = 5 as an index. As the list is of length 5, the max index is 4, causing the IndexOutOfBoundsException.
There are two main ways I could see to fix this:
Reconsider whether you really need to repeat the same block of code twice in the while loop - this adds a bit of unneeded complexity, and reduces how often the while conditions are checked.
Update the while condition to check that any (messageType*2)+1 which will occur during the iteration will still be within the bounds of the array.

Java - How shorten if statements using lambda expressions?

First of all, I'm aware that there is a similar questions like this. The answer to that question, however, did not help me.
I have the following code:
boolean result = fields[x][y + 1].getRing().getPlayer() == player || fields[x][y - 1].getRing().getPlayer() == player || fields[x + 1][y].getRing().getPlayer() == player || fields[x - 1][y].getRing().getPlayer() == player
The code is supposed to check if there are any rings of the current player above, under or next to the current field.
I'm trying to make this code more readable by using a lambda expression, but I can't get it right. I'm not sure whether this is even possible, though.
I tried to replace fields[x][y] by a variable field and then have field become fields[x][y+1], fields[x][y-1], fields[x+1][y], fields[x-1][y]
boolean result = field.getRing().getPlayer() == player -> field = {fields[x][y+1], fields[x][y-1], fields[x+1][y], fields[x-1][y]};
But this gives me a syntax error, which I expected, since field = {fields[x][y+1], fields[x][y-1], fields[x+1][y], fields[x-1][y]}; sets field to an array, and does not iterate over that array.
Is there any way I can make this code shorter using lambda expression?
You keep repeating the same condition, on 4 different values. So what you want in fact is to avoid this repetition, and write the condition once. And you want to test if any of the 4 values match the condition. So start by storing the 4 values in a collection:
List<Field> neighbors = Arrays.asList(fields[x + 1][y],
fields[x - 1][y],
fields[x][y + 1],
fields[x][y - 1]);
Then test if any of those values match the condition:
boolean result = neighbors.stream().anyMatch(field -> field.getRing().getPlayer() == player);
This doesn't necessarily make the code faster or shorter, but it makes it more readable, and DRY.
I don't think lambdas will help here. What I think is better is just to introduce some methods so that the code is more readable.
For example, you could make four methods ringAbove, ringBelow, ringRight and ringLeft and that would make the code a little more readable.
boolean result = ringAbove(x,y) || ringBelow(x,y) || ringRight(x,y) || ringLeft(x,y);
Now just implement each method, with a bit of refactoring:
private boolean ringAbove( int x, int y ) {
return ringAt( x+1, y);
}
The other three methods can be implemented similarly.
I don't really understand this code, but lets just assume it works. player will need to be available as a global variable, or you'll need to also pass it as a parameter.
private boolean ringAt( int x, int y ) {
if( x < 0 || y < 0 || x >= fields.length || y >= fields[x].length )
return false;
return fields[x][y].getRing().getPlayer() == player;
}
Here is another "tiny embedded domain specific language" for
dealing with positions and fields. It makes use of Java8 Streams and lambdas.
The method neighborhood
abstracts the idea of the shape of a discrete geometric neighborhood, so
that is becomes very easy to deal with all kind of neighborhoods on the
grid, for example with something like this:
# ### # #
#x# #x# # #
# ### x
# #
# #
You wanted the first case, but in the code below, it would be very easy to
replace the concept of "neighborhood" by the 8-cell neighborhood (second case), or by something even weirder, like for example the allowed moves of a knight in chess (third case).
The method neighboringFields makes use of the stream of the purely geometric positions, performs some additional checks on it (to ensure that you don't leave the game universe), and then enumerates all the fields with their content.
You can then use these streams of fields to quickly check various predicates on them, for example using the allMatch and anyMatch methods, as is shown in the very last method checkRingsInNeighborhood,
so that the unwieldy if-expression collapses to just this:
return neighboringFields(pos).anyMatch(
field -> field.getRing().getPlayer() == player
);
Here is the full code snippet:
import java.util.function.*;
import java.util.stream.*;
class NeighborPositions {
// Mock up implementations of `Ring`, `Player`, and `Position`,
// whatever those things are
public static class Ring {
private Player player;
public Ring(Player player) {
this.player = player;
}
public Player getPlayer() {
return this.player;
}
}
public static class Player {
private final String name;
public Player(String name) {
this.name = name;
}
}
public static class Field {
private final Ring ring;
public Field(Ring ring) {
this.ring = ring;
}
public Ring getRing() {
return this.ring;
}
}
// you probably want to fill it somehow...
public static int DIM_X = 100;
public static int DIM_Y = 42;
public static Field[][] fields = null;
/** Position on a rectangular grid */
public static class Position {
final int x;
final int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
}
/** Shortcut for accessing fields at a given position */
public static Field field(Position p) {
return fields[p.x][p.y];
}
/** Generates stream of neighboring positions */
public static Stream<Position> neighborhood(Position pos) {
return Stream.of(
new Position(pos.x + 1, pos.y),
new Position(pos.x - 1, pos.y),
new Position(pos.x, pos.y + 1),
new Position(pos.x, pos.y - 1)
);
}
/** Generates stream of neighboring fields */
public static Stream<Field> neighboringFields(Position pos) {
return neighborhood(pos).
filter(p -> p.x >= 0 && p.x < DIM_X && p.y >= 0 && p.y < DIM_Y).
map(p -> field(p));
}
/** This is the piece of code that you've tried to implement */
public static boolean checkRingsInNeighborhood(Position pos, Player player) {
return neighboringFields(pos).anyMatch(
field -> field.getRing().getPlayer() == player
);
}
}
You obviously shouldn't try to cram everything into a single file and declare it public static, it's just an example.
You could create a BiFunction<Integer, Integer, Player> that, given x and y coordinates, returns a Player:
BiFunction<Integer, Integer, Player> fun = (coordX, coordY) ->
fields[coordX][coordY].getRing().getPlayer();
Now, to check whether a given player's ring is above, under or next to a given pair of coordinates, you could use:
boolean result = List.of(
fun.apply(x, y - 1),
fun.apply(x, y + 1),
fun.apply(x - 1, y),
fun.apply(x + 1, y))
.contains(player);
This uses Java 9's List.of. If you are not in Java 9 yet, just use Arrays.asList.
Besides, it also uses the List.contains method, which checks if a given object belongs to the list by means of the Objects.equals method, which in turn uses the equals method (taking care of nulls). If Player doesn't override equals, then identity equality == will be used as a fallback.

Scope of variable instantiated inside a method - Java

Is this code safe in Java?
public class HelloWorld {
public static void main (String args[]) {
HelloWorld h = new HelloWorld();
int y = h.getNumber(5);
int z = h.getNumber (6);
if (y == 10)
System.out.println("true");
}
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
}
My co-worker says that int number will be placed on the stack and when getNumber returns it will be popped off and could potentially be overwritten.
Is the same code potentially unsafe in C?
The HelloWorld class has no fields, and is therefore immutable. You can call your getNumber(x) function as many times as you'd like, from any thread, using the same object, and it will always give the same result for the same argument.
Maybe your co-worker is recalling horror stories in C where you can have something like static int number, which "belongs" to the method and which would get overwritten. Or maybe she's thinking about "return by reference"; even if it were, you'd be referencing a brand-new object every time because number is newly instantiated for every method call.
Your coworker is correct, sort of, but they apparently misunderstand what is going on.
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
Yes the value of 5 + 5 or 5 + 6 will be placed on the stack, but there is no danger of them being overwritten, they will properly be placed into y or z.
I suspect the confusion is from C (this type code works fine in C as well), but for pointers instead of primitives. Returning a result of malloc from a function in C can be "challenging" if you don't do it right.

InvocationTargetException while trying to add variables to a new object

I am trying to send two variables from one sketch to another, using the oscP5 library for processing.
The message I am sending is created like this:
OscMessage myMessage = new OscMessage("/test");
myMessage.add(title);
myMessage.add("Zeit");
oscP5.send(myMessage, remoteLocation);
In the second sketch, I receive the data like that:
void oscEvent(OscMessage theOscMessage) {
if(theOscMessage.checkAddrPattern("/test")) {
String title = theOscMessage.get(0).stringValue();
String layoutType = theOscMessage.get(1).stringValue();
addToQueue(title, layoutType);
}
}
And here my simplified addToQueue function:
void addToQueue(String title, String layoutType) {
if(!existsInQueues(title)) {
upcomingHeadlines.add(new Headline(title, printAxis, scrollSpeed, layoutType));
}
}
Every time I start the sketches, I get the error:
ERROR # OscP5 ERROR. an error occured while forwarding an OscMessage to a method in your program. please check your code for any possible errors that might occur in the method where incoming OscMessages are parsed e.g. check for casting errors, possible nullpointers, array overflows ... .
method in charge : oscEvent java.lang.reflect.InvocationTargetException
I have been able to track the problem down to the layoutType-Variable. If I change
String layoutType = theOscMessage.get(1).stringValue();
to
String layoutType = "Zeit";
no error occurs.
That is quite confusing, because both versions should have the same result.
The error message does not help me in any way.
Edit
I have compared the two possible variables like that:
String layoutType = theOscMessage.get(1).stringValue();
String layoutTypeB = "Zeit";
if(layoutType.equals(layoutTypeB)) println("Same String!");
Since gets printed to the console, both have to be the same … I really do not know where to search for an error anymore.
Edit 2
I have wrapped my second sketch in try {...} catch(Exception ex) {ex.printStackTrace();} like that:
void oscEvent(OscMessage theOscMessage) {
try {
if(theOscMessage.checkAddrPattern("/test")) {
if(debug && debugFeed) println("Received message from other sketch.");
String title = theOscMessage.get(0).stringValue();
String layoutTypeO = (String)theOscMessage.get(1).stringValue();
String layoutType = "Zeit";
if(debug && debugTemp) {
if(layoutType.equals(layoutTypeO)) println("IS DOCH GLEICH!");
}
if(debug && debugFeed) println("Parsed Information.");
if(debug && debugFeed) println("-----");
addToQueue(title, layoutTypeO);
}
} catch(Exception ex) {ex.printStackTrace();}
}
That gives me this error as result:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at printer$Headline.useLayout(printer.java:260)
at printer$Headline.<init>(printer.java:188)
at printer.addToQueue(printer.java:407)
at printer.oscEvent(printer.java:395)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at oscP5.OscP5.invoke(Unknown Source)
at oscP5.OscP5.callMethod(Unknown Source)
at oscP5.OscP5.process(Unknown Source)
at oscP5.OscNetManager.process(Unknown Source)
at netP5.AbstractUdpServer.run(Unknown Source)
at java.lang.Thread.run(Thread.java:744)
Edit 4
Constructor for my Headline-Class:
class Headline {
//Define Variables
Layout layout;
String title, lastHeadline;
float yPos, speed;
float transparency = 255;
boolean fullyPrinted = false;
int boundingBoxHeight;
// Initialize Class Function
Headline(String t, float y, float s, String lay) {
title = t;
yPos = y;
speed = s;
layout = useLayout(lay);
boundingBoxHeight = calculateTextHeight(title);
}
You might want to know about useLayout() too, so here it is:
Layout useLayout(String name) {
ArrayList layoutVariants = new ArrayList<Layout>();
int existingLayouts = layouts.size();
Layout chosenLayout;
for(int i = 0; i < existingLayouts; i++) {
Layout currentLayout = (Layout)layouts.get(i);
if(currentLayout.layoutType == name) {
layoutVariants.add(currentLayout);
}
}
if(layoutVariants != null) {
int rand = (int)(Math.random() * layoutVariants.size());
chosenLayout = (Layout)layoutVariants.get(rand);
} else {
chosenLayout = (Layout)layouts.get((int)(Math.random() * existingLayouts));
}
return chosenLayout;
}
There are two problems with your code, and both of them are in your useLayout method.
The first problem is that you are not comparing Stringss correctly on this line:
if(currentLayout.layoutType == name) {
name is a String, and I assume currentLayout.layoutType is too. Two Strings that are equal but not the same will not compare equal under ==. As a result of this, your layoutVariants list will quite probably be empty at the end of the for loop.
This line should read:
if(currentLayout.layoutType.equals(name)) {
See also this question.
The second problem is that you don't correctly handle the case that the layoutVariants list is empty. The problem is on this line:
if(layoutVariants != null) {
layoutVariants will never be null, so the else branch of this if statement will never execute. Because layoutVariants.size() will be zero, rand will always be zero. Trying to get the element at index 0 in an empty ArrayList will give you precisely the IndexOutOfBoundsException you are seeing.
I imagine you want the else block to execute if the layout name given isn't recognised, in other words, if the layoutVariants list is empty, rather than null. In that case, change this line to
if(!layoutVariants.isEmpty()) {
Note the ! (not-operator) before layoutVariants. You want the code under the if statement to run if the layoutVariants element is not empty.
EDIT in response to your comments: a null ArrayList is very much not the same as an empty one. null is a special value meaning that the variable doesn't have an object of a given type.
Let's try a real-world analogy: a shopping bag. If you have an empty bag, or no bag at all, then you have no shopping either way. However, you can put things into an empty bag, and count how many items it contains, for example. If you don't have a bag, then it doesn't make sense to put an item in it, as there's no bag to put the item into. null represents the case where you don't have a bag.
Similarly, a String is a collection of characters, and the collection of characters can exist even if it doesn't contain any characters.
isEmpty() can be used for any collection, and, if you're using Java 6 or later, Strings as well. Off the top of my head I can't name any other classes that have an isEmpty method. You'll just have to consult the documentation for these classes to find out.
I've not worked with Processing much, but I am aware that Processing is built on Java, so I would expect any standard Java method to work. Also, I wouldn't worry about 'clearing' a variable: the JVM is generally very good at clearing up after you. There's certainly nothing I can see wrong with your code in this respect.
EDIT 2 in response to your further comment: ArrayList arr; declares a variable of type ArrayList. However, the variable arr is uninitialized: it does not have a value (not even null) and it is an error to try to read the value of this variable before you have assigned a value to it:
ArrayList arr;
System.out.println(arr); // compiler error: arr might not have been initialised.
Assign null and the code then compiles:
ArrayList arr = null;
System.out.println(arr); // prints 'null'.
It's not often you need to declare a variable and not give it a name, but one common case is where you want to assign different values to the same variable on both sides of an if statement. The following code doesn't compile:
int y = getMeSomeInteger(); // assume this function exists
if (y == 4) {
int x = 2;
} else {
int x = 5;
}
System.out.println(x); // compiler error: cannot find symbol x
The reason it doesn't compile is that each variable x is only available within the braces { and } that contain it. At the bottom, neither variable x is available and so you get a compiler error.
We need to declare x further up. We could instead write the following;
int y = getMeSomeInteger(); // assume this function exists
int x = 0;
if (y == 4) {
x = 2;
} else {
x = 5;
}
System.out.println(x);
This code compiles and runs, but the value 0 initially assigned to x is never used. There isn't a lot of point in doing this, and we can get rid of this unused value by declaring the variable but not immediately giving it a value.
int y = getMeSomeInteger(); // assume this function exists
int x;
if (y == 4) {
x = 2;
} else {
x = 5;
}
System.out.println(x);

Categories

Resources