Learn Access, Encapsulation, and Scope: Instructions
Learn Access, Encapsulation, and Scope: Instructions
Course Menu -java
Connected to Codeca
Learn
ACCESS, ENCAPSULATION, AND SCOPE
What are Access and Scope?
As our Java programs begin to get bigger and we begin to have multiple Objects and Classes that
interact with each other, the concepts of access and scope come into play. To oversimplify
things, the concepts of access and scope both center around what parts of your programs can
interact with specific variables or methods from other parts of your program. Let’s take a brief
look at some of the concepts we’ll cover:
Access
Scope
Instructions
For now, let’s get a preview of how access works in Java. In the code editor, you should see two
files - Bank.java and CheckingAccount.java. Take a look at each file and notice the instance
variables are declared using the private keyword. When you’re ready, select the Bank.java file,
and run your code.
You should get two errors! Take a look at the main() method in Bank.java. Our Bank is trying to
access some instance variables from a CheckingAccount that is marked as private! Take a look at
the error message to see which variables are giving us trouble.
Bank.java
public Bank(){
System.out.println(bankOfGods.accountOne.name);
System.out.println(bankOfGods.accountOne.balance);
Checkingaccount.java
balance = inputBalance;
}
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
The public Keyword
After running the code in the last exercise, you should be developing an intuition on what
the public and private keywords are doing. These keywords are defining what parts of your code
have access to other parts of your code.
We can define the access of many different parts of our code including instance variables,
methods, constructors, and even a class itself. If we choose to declare these as public this means
that any part of our code can interact with them - even if that code is in a different class!
One final thing to note is that for the purposes of this lesson, we’ll almost always make our
classes and constructors public. While you can set them to private, it’s fairly uncommon to do
so. Instead, we’ll focus on why you might make your instance variables and methods private.
We’ll start looking into the private keyword in the next exercise.
Instructions
1.
Once again we’ve given you a Bank class and a CheckingAccount class. First, take a look
at CheckingAccount.java to see what methods and variables have been set to private or public.
Then, switch to Bank.java, look at the main method, and hit the “Run” button. You should get
an error. Why?
Checkpoint 2 Passed
Hint
The main method is trying to access three different fields from CheckingAccount that are
all private. Those would need to be public in order for Bank‘s main() method to run.
2.
In Bank.java‘s main() method, we’re trying to access three different private fields from
the CheckingAccount class. Edit the checking account class to make those fields public. Make
sure to edit only the fields you need in order to make Bank‘s main() method run — don’t change
any of the other fields in CheckingAccount.
public Bank(){
System.out.println(bankOfGods.accountOne.name);
bankOfGods.accountOne.addFunds(5);
bankOfGods.accountOne.getInfo();
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Access, Encapsulation, and Scope: The public Keyword
Learn
ACCESS, ENCAPSULATION, AND SCOPE
The public Keyword
After running the code in the last exercise, you should be developing an intuition on what
the public and private keywords are doing. These keywords are defining what parts of your code
have access to other parts of your code.
We can define the access of many different parts of our code including instance variables,
methods, constructors, and even a class itself. If we choose to declare these as public this means
that any part of our code can interact with them - even if that code is in a different class!
One final thing to note is that for the purposes of this lesson, we’ll almost always make our
classes and constructors public. While you can set them to private, it’s fairly uncommon to do
so. Instead, we’ll focus on why you might make your instance variables and methods private.
We’ll start looking into the private keyword in the next exercise.
Instructions
1.
Once again we’ve given you a Bank class and a CheckingAccount class. First, take a look
at CheckingAccount.java to see what methods and variables have been set to private or public.
Then, switch to Bank.java, look at the main method, and hit the “Run” button. You should get
an error. Why?
Checkpoint 2 Passed
Hint
The main method is trying to access three different fields from CheckingAccount that are
all private. Those would need to be public in order for Bank‘s main() method to run.
2.
In Bank.java‘s main() method, we’re trying to access three different private fields from
the CheckingAccount class. Edit the checking account class to make those fields public. Make
sure to edit only the fields you need in order to make Bank‘s main() method run — don’t change
any of the other fields in CheckingAccount.
Hint
Bank‘s main() method is trying to directly access a CheckingAccount‘s .name instance variable.
That variable is private. It’s also trying to use CheckingAccount‘s private .addFunds() method.
Finally, Bank‘s main() method is trying to call its own .getInfo() method. This method tries to
print the private .address instance variable of all of its CheckingAccounts.
Checkingaccount.java
name = inputName;
balance = inputBalance;
id = inputId;
balance += fundsToAdd;
System.out.println("This checking account belongs to " + name +". It has " + balance + " dollars in it.");
Bank.java
public Bank(){
System.out.println(bankOfGods.accountOne.name);
bankOfGods.accountOne.addFunds(5);
bankOfGods.accountOne.getInfo();
}
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
The private Keyword and Encapsulation
By now you’re probably catching onto what the private keyword does. When a Class’ instance
variable or method is marked as private, that means that you can only access those structures
from elsewhere inside that same class. Let’s look back at our DogSchool example:
At this point, you might be thinking to yourself “Why even bother with any of this? In the last
exercise, my code was broken until I flipped some variables and methods to public. Why don’t I
just make everything public?”
While those are valid points, sometimes restricting our code is actually useful from a design
perspective. This is one of the core ideas behind encapsulation. By making our instance variables
(and some methods) private, we encapsulate our code into nice little bundles of logic.
For example, a Bank object doesn’t necessarily need to know the inner workings of
a CheckingAccount object. It doesn’t need to know that the money is stored in a field
named money, or that interest is added to an account by using a method named .addInterest(). In
fact, if it had access to those fields or methods, it’s possible that someone using a Bank object
could change things in a CheckingAccount without realizing it. By limiting access by using
the private keyword, we are able to segment, or encapsulate, our code into individual units.
Note that we don’t necessarily want to completely block everything from other classes. In the
next exercise, we’ll get into when you might want to make methods public — we’ll take a look
at getter and setter methods.
Instructions
1.
We’ve changed the variables and methods in CheckingAccount.java back to private. To begin,
go to Bank.java and run your code. Let’s confirm that we get errors when a Bank tries to
access private data from a CheckingAccount
2.
A Bank couldn’t access a CheckingAccount‘s private structures. Let’s prove to ourselves
that CheckingAccount can access its own private fields.
Bank.java
public class Bank{
public Bank(){
System.out.println(bankOfGods.accountOne.name);
bankOfGods.accountOne.addFunds(5);
bankOfGods.accountOne.getInfo();
CheckingCCCOUNT.JAVA
public Bank(){
System.out.println(bankOfGods.accountOne.name);
bankOfGods.accountOne.addFunds(5);
bankOfGods.accountOne.getInfo();
name = inputName;
balance = inputBalance;
balance += fundsToAdd;
}
private void getInfo(){
System.out.println("This checking account belongs to " + name +". It has " + balance + " dollars in it.");
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
The private Keyword and Encapsulation
By now you’re probably catching onto what the private keyword does. When a Class’ instance
variable or method is marked as private, that means that you can only access those structures
from elsewhere inside that same class. Let’s look back at our DogSchool example:
At this point, you might be thinking to yourself “Why even bother with any of this? In the last
exercise, my code was broken until I flipped some variables and methods to public. Why don’t I
just make everything public?”
While those are valid points, sometimes restricting our code is actually useful from a design
perspective. This is one of the core ideas behind encapsulation. By making our instance variables
(and some methods) private, we encapsulate our code into nice little bundles of logic.
For example, a Bank object doesn’t necessarily need to know the inner workings of
a CheckingAccount object. It doesn’t need to know that the money is stored in a field
named money, or that interest is added to an account by using a method named .addInterest(). In
fact, if it had access to those fields or methods, it’s possible that someone using a Bank object
could change things in a CheckingAccount without realizing it. By limiting access by using
the private keyword, we are able to segment, or encapsulate, our code into individual units.
Note that we don’t necessarily want to completely block everything from other classes. In the
next exercise, we’ll get into when you might want to make methods public — we’ll take a look
at getter and setter methods.
Instructions
1.
We’ve changed the variables and methods in CheckingAccount.java back to private. To begin,
go to Bank.java and run your code. Let’s confirm that we get errors when a Bank tries to
access private data from a CheckingAccount
Checkpoint 2 Passed
2.
A Bank couldn’t access a CheckingAccount‘s private structures. Let’s prove to ourselves
that CheckingAccount can access its own private fields.
Hint
You can create a new CheckingAccount like this:
Hint
You’ll want to print myAccount.balance
4.
Let’s also confirm that we can use private methods. Call addFunds() to add 5 dollars
to myAccount‘s balance. Then print the balance again to confirm the money was added. Continue
to do this work in the main() method of CheckingAccount.java.
Checkpoint 5 Passed
Hint
You’ll want to call myAccount.addFunds() and use 5 as an argument to the method.
name = inputName;
balance = inputBalance;
balance += fundsToAdd;
System.out.println("This checking account belongs to " + name +". It has " + balance + " dollars in it.");
System.out.println(myAccount.balance);
myAccount.addFunds(5);
System.out.println(myAccount.balance);
BANK.JAVA
public class Bank{
public Bank(){
System.out.println(bankOfGods.accountOne.name);
bankOfGods.accountOne.addFunds(5);
bankOfGods.accountOne.getInfo();
}
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
Accessor and Mutator Methods
When writing classes, we often make all of our instance variables private. However, we still
might want some other classes to have access to them, we just don’t want those classes to know
the exact variable name. To give other classes access to a private instance variable, we would
write an accessor method (sometimes also known as a “getter” method).
Instructions
1.
Take a look at the main() method of Bank.java. Right now it’s trying to directly access and
change the balance in a checking account. Unfortunately, that instance variable is private. Run
your code with Bank.java open. You should expect an error.
2.
Let’s go to CheckingAccount.java and write an accessor method for the balance instance field.
Your method should be named getBalance(). This method should be public.
When you’re done writing that method, go back to the main() method in Bank.java and change
the code to use that new method.
Hint
getBalance() should return an int. Then, in Bank.java, replace the reference
to bankOfGods.accountOne.balance with bankOfGods.accountOne.getBalance().
3.
Let’s do the same for a mutator method. In CheckingAccount.java, write a mutator method
named setBalance() that has an int parameter named newBalance. The method should set
the balance instance variable to the value passed into the method.
After writing this method, go back to Bank.java and add a line of code to your main() method
where you use setBalance() to set accountOne‘s balance to 5000.
After setting the balance to 5000, use your .getBalance() method again to print out the new
balance.
Hint
Your method should be a void method — it doesn’t return anything. In Bank.java,
use bankOfGods.accountOne.setBalance(5000).
public Bank(){
System.out.println(bankOfGods.accountOne.getBalance());
bankOfGods.accountOne.setBalance(5000);
System.out.println(bankOfGods.accountOne.getBalance());
name = inputName;
balance = inputBalance;
id = inputId;
}
return balance;
balance = newBalance;
}
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
Scope: Local Variables
In addition to access modifiers like public and private, the scope of the variable also determines
what parts of your code can access that variable.
The scope of a variable is determined by where the variable is declared. For example, because
instance variables are declared inside a class but outside any methods or constructors, all
methods and constructors are within the scope of that variable. For example, in the code block
below, constructors and methods of the Dog class are using the Dog instance variables
like name and age:
class Dog{
public String name;
public int age;
public int weight;
public Dog(){
name = "Winston";
age = 8;
weight = 30;
}
This idea of scope extends to conditionals and loops as well. If you declare a variable inside the
body of a conditional or in a loop, that variable can only be used inside that structure. This also
includes the variable you’re using as your looping variable. For example, consider the following
block of code:
Instructions
1.
Take a look at the main() method which tries to sum the values from a list. Right now, we’re
looping through the values and trying to store the sum in a variable called sum. However, that
variable is declared inside the for loop.
There are two problems with this. The first is a logical error. Since we’re setting int sum = 0; at
the start of the loop, every time the loop runs, sum gets reset back to 0.
However, there is also a syntactical error. Right now we try to print sum after the loop. But that’s
outside of sum‘s scope since the variable was declared inside the loop.
Run your code as-is. You should expect to get an error related to the scope of sum.
2.
Move the line of code int sum = 0; to be above the for loop. Now the for loop has access
to sum and we’re able to return sum after the loop finishes.
After moving the line of code, run your code to test the main() method.
Hint
Your code should be structured like this. Notice the location of sum‘s declaration:
scopeexample.java
int sum = 0;
sum += myArray[i];
System.out.println(sum);
}
ACCESS, ENCAPSULATION, AND SCOPE
Scope: The this Keyword
Often times when creating classes, programmers will create local variables
with the same name as instance variables. For example, consider the code
block below:
}
}
We have an instance variable named name, but the method speakNewName has a
parameter named name. So when the method tries to print name, which variable
will be printed? By default, Java refers to the local variable name. So in this
case, the value passed to the parameter will be printed and not the instance
variable.
If we wanted to access the instance variable and not the local variable, we
could use the this keyword.
a.speakNewName("Winston");
// "Fido", the instance variable of Dog a is printed.
"Winston" is ignored
b.speakNewName("Darla");
// "Odie", the instance variable of Dog b is printed.
"Darla" is ignored.
}
}
The this keyword is a reference to the current object. We used this.name in
our speakNewName() method. This caused the method to print out the value
stored in the instance variable name of whatever Dog Object
called speakNewName(). (Note that in this somewhat contrived example, the local
variable name used as a parameter gets completely ignored).
Oftentimes, you’ll see constructors have parameters with the same name as
the instance variable. For example, you might see something like:
Instructions
1.
Take a look at the instance variables for our SavingsAccount class. There are
three of them. owner, balanceDollar, balanceEuro. Next, take a look at the
constructor we’ve started for you. The job of the constructor is to initialize
these instance variables.
Complete the constructor to give value to all three instance variables. The
instance variable owner should be set to the local variable owner. The instance
variable balanceDollar should be set equal to the local variable balanceDollar.
Finally, the instance variable balanceEuro should be set equal to the local
variable balanceDollar multiplied by 0.85. (Right now, every dollar is
worth 0.85 euros.)
Hint
You can set the instance variable owner equal to the local variable owner by
writing this.owner = owner; inside the constructor.
2.
Next, look at the addMoney() method. This method should add the value stored
in the parameter balanceDollar to the instance variable balanceDollar. Before
adding the money to the account, print out the statement "Adding ____
dollars to the account.".After adding the money, print the statement "The new
balance is _____ dollars.". Be careful of spacing, capitalization, and
punctuation with your print statements.
Finally, when writing the second print statement, make sure to print the
instance variable, using this.balanceDollar.
Savingaccount.java
this.owner = owner;
this.balanceDollar = balanceDollar;
this.balanceDollar += balanceDollar;
zeusSavingsAccount.addMoney(2000);
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
Using this With Methods
We’ve seen how the this works with variables, but we can also use the this with methods.
Finally, this can be used as a value for a parameter. Let’s say a method exists that takes
a Computer as a parameter (that method’s signature might be something like public void
pairWithOtherComputer(Computer other) . If you’re writing another method of the Computer, and
want to call the pairWithOtherComputer() method, you could use this as the parameter. That call
might look something like this.pairWithOtherComputer(this). You’re using the current object to
call the method and are passing that object as that method’s parameter.
Instructions
1.
We’ve given you a Person class with three instance variables — age, wisdom, and fitness. Those
values all get initialized to different values when the constructor is called. We’ve also provided
you with mutator methods for all three variables.
When you’re done writing hasBirthday() look at the main() method to see how we’re calling it.
Checkpoint 2 Passed
Hint
Within the hasBirthday() method, you should be calling three methods using the this keyword
— this.setAge(), this.setWisdom() and this.setFitness().
Each of those methods take a parameter. The parameter for setAge() should be this.age + 1 —
we’re setting the new age to be the current age plus one.
this.age = inputAge;
this.wisdom = inputAge * 5;
this.age = newAge;
this.wisdom = newWisdom;
this.fitness = newFitness;
}
public void hasBirthday(){
this.setAge(this.age + 1);
this.setWisdom(this.wisdom + 5);
this.setFitness(this.fitness - 3);
emily.hasBirthday();
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
Other Private Methods
Now that we’ve seen how methods can call other methods using this., let’s look at a situation
where you might want to use private methods. Oftentimes, private methods are helper methods
— that is to say that they’re methods that other, bigger methods use.
Well, in order to get that information, we might want to break that larger method into several
helper methods. For example, inside getAccountInformation(), we might want to call a function
called calculateNextMonthInterest(). That helper method should probably be private. There’s
no need for a Bank to call these smaller helper methods — instead, a Bank can call the
one public method, and rely on that method to do all of the complicated work by calling
smaller private methods.
Instructions
1.
Let’s implement what we described in the narrative. We’ve written
our getAccountInformation() method in the CheckingAccount.java class. But we haven’t yet
implemented the calculateNextMonthInterest() method. This should be a private method and
return a double — the balance of the account multiplied by the interestRate. Write that function.
You should see an error since you’re trying to use a Bank to call a private method from
a Checking
Bank.java
public Bank(){
bankOfGods.accountOne.getAccountInformation();
bankOfGods.accountOne.calculateNextMonthInterest();
}
Checkingaccount.java
--------------------------/
this.name = inputName;
this.balance = inputBalance;
this.id = inputId;
this.interestRate = 0.02;
return this.balance;
}
// Write the calculateNextMonthInterest() here
}
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Learn
ACCESS, ENCAPSULATION, AND SCOPE
Review
Nice work! In this lesson, we dove into some of the more subtle features of classes with a focus
on access, encapsulation, and scope. Here are some of the main takeaways from this lesson:
Instructions
We’ve given you our full code for our Bank and CheckingAccount classes. Feel free to continue to
experiment with the public and private keywords to get a better understanding of what code has
access to certain structures.
https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
STATIC VARIABLES AND METHODS
Static Variables
We’ll begin writing our own static methods soon, but before we do, let’s take a look at static
variables. Much like static methods, you can think of static variables as belonging to the class
itself instead of belonging to a particular object of the class.
Just like with static methods, we can access static variables by using the name of the class and
the . operator. Finally, we declare static variables by using the static keyword during
declaration. This keyword usually comes after the variable’s access modifier (public or private).
When we put this all together, we might end up with a class that looks something like this:
//Instance variables
public int age;
public String name;
Instructions
1.
We’re going to be building out an ATM class that has both static and non-static variables. We’ve
started by giving you an ATM class with non-static variables, a constructor, and some methods.
In the main() method, use the constructor to create two ATMs named firstATM and secondATM. Use
the constructor so the first ATM has 1000 dollars in it and the second has 500.
If you’d like, you could print out each ATM‘s money variable to confirm you created them
successfully.
Checkpoint 2 Passed
Hint
You can use the constructor to create an ATM with 50 dollars in it like so:
First, we want to create a variable to keep track of how much money is in the system across
all ATMs. This should be a public static int variable and should be named totalMoney. This
variable should begin with a value of 0.
Second, we want to know how many ATMs there are in the system. Again, this should be a public
static int variable that has an initial value of 0. Name this variable numATMs.
Checkpoint 3 Passed
Hint
Create these two variables where you would create your instance variables. The first should
be public static int totalMoney = 0;.
3.
Let’s take a look at the first of these static variables. In the main() method, print
your totalMoney variable three different times. The first time, you should use ATM.totalMoney, the
second time you should use firstATM.totalMoney, and the third time you should
use secondATM.totalMoney. Do you expect these print statements to be the same or different?
Right now the value stored in totalMoney doesn’t actually represent the total amount of money
stored in all ATMs. In the next exercise, we’ll look into how to change the value of static
variables.
Checkpoint 4 Passed
Hint
You should see the same value printed each time. Every ATM object shares the
same totalMoney variable.
// Instance variables
this.money = inputMoney;
System.out.println(firstATM.money);
System.out.println(secondATM.money);
System.out.println(ATM.totalMoney);
System.out.println(firstATM.totalMoney);
System.out.println(secondATM.totalMoney);
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Static Variables and Methods: Modifying Static Variables
Learn
STATIC VARIABLES AND METHODS
Modifying Static Variables
Now that we’ve created a couple of static variables, let’s start to edit them. The good news is that
editing static variables is similar to editing any other variable. Whether you’re writing code in a
constructor, a non-static method, or a static method, you have access to static variables.
Before we jump into the checkpoints, let’s think about times when you might want to edit static
variables. Often times, you’ll see static variables used to keep track of information about all
objects of a class. For example, our variable numATMs is keeping track of the total number of ATMs
in the system. Therefore, every time an ATM is created (using the constructor), we should increase
that variable by 1. If we could somehow destroy an ATM, the method that destroys it should
decrease numATMs static variable by 1.
Similarly, we have a variable named totalMoney. This variable is keeping track of all money
across all ATMs. Whenever we remove money from an ATM using the non-
static withdrawMoney() method, we should modify the money instance variable for that particular
ATM as well as the totalMoney variable. In doing so, all ATMs will know how much money is in
the system.
Instructions
1.
Edit the constructor to increase numATMs by 1 every time an ATM is created. In the main method,
we’re printing out numATMs before and after creating some ATMs. You should expect to see that
number go up as you create ATMs.
Hint
In the constructor, you’ll want to add numATMs += 1;
2.
Edit the constructor so when a new ATM is created, the amount of money that ATM starts with gets
added to the static variable totalMoney.
Hint
You’ll want to add inputMoney to totalMoney.
3.
Edit the withdrawMoney() method so when money is taken out of a specific ATM, the static
variable totalMoney also reflects that change.
Take a look at the main() method — we’re printing totalMoney before and after withdrawing
money from a couple of ATMs.
Hint
Right after this.money -= amountToWithdraw;, write totalMoney -= amountToWithdraw;.
// Static variables
// Instance variables
this.money = inputMoney;
this.money -= amountToWithdraw;
firstATM.withdrawMoney(500);
secondATM.withdrawMoney(200);
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
STATIC VARIABLES AND METHODS
Modifying Static Variables
Now that we’ve created a couple of static variables, let’s start to edit them. The good news is that
editing static variables is similar to editing any other variable. Whether you’re writing code in a
constructor, a non-static method, or a static method, you have access to static variables.
Before we jump into the checkpoints, let’s think about times when you might want to edit static
variables. Often times, you’ll see static variables used to keep track of information about all
objects of a class. For example, our variable numATMs is keeping track of the total number of ATMs
in the system. Therefore, every time an ATM is created (using the constructor), we should increase
that variable by 1. If we could somehow destroy an ATM, the method that destroys it should
decrease numATMs static variable by 1.
Similarly, we have a variable named totalMoney. This variable is keeping track of all money
across all ATMs. Whenever we remove money from an ATM using the non-
static withdrawMoney() method, we should modify the money instance variable for that particular
ATM as well as the totalMoney variable. In doing so, all ATMs will know how much money is in
the system.
Instructions
1.
Edit the constructor to increase numATMs by 1 every time an ATM is created. In the main method,
we’re printing out numATMs before and after creating some ATMs. You should expect to see that
number go up as you create ATMs.
Checkpoint 2 Passed
Hint
In the constructor, you’ll want to add numATMs += 1;
2.
Edit the constructor so when a new ATM is created, the amount of money that ATM starts with gets
added to the static variable totalMoney.
Checkpoint 3 Passed
Hint
You’ll want to add inputMoney to totalMoney.
3.
Edit the withdrawMoney() method so when money is taken out of a specific ATM, the static
variable totalMoney also reflects that change.
Hint
Right after this.money -= amountToWithdraw;, write totalMoney -= amountToWithdraw;.
Atm.java
// Static variables
// Instance variables
this.money = inputMoney;
numATMs += 1;
totalMoney += inputMoney;
totalMoney -= amountToWithdraw;
firstATM.withdrawMoney(500);
secondATM.withdrawMoney(200);
Review
Great work! You now have an understanding of what the static keyword does.
In fact, if you’ve made it this far in your Java lessons, you probably have a
pretty good sense of what all the keywords and jargon are doing in public
static void main(String[] args). Take a moment to celebrate — that line of
code can be incredibly intimidating for new learners and it’s a real
accomplishment to learn about all of those different pieces.
To review, here are some of the main takeaways about static methods and
variables:
Static methods and variables are associated with the class as a whole,
not objects of the class.
Static methods and variables are declared as static by using
the static keyword upon declaration.
Static methods cannot interact with non-static instance variables. This is
due to static methods not having a this reference.
Both static methods and non-static methods can interact with static
variables.
Instructions
// Static variables
// Instance variables
this.money = inputMoney;
numATMs += 1;
totalMoney += inputMoney;
this.money -= amountToWithdraw;
totalMoney -= amountToWithdraw;
System.out.println(totalMoney / numATMs);
firstATM.withdrawMoney(500);
secondATM.withdrawMoney(200);
ATM.averageMoney();
}
Project:
LEARN JAVA
2D Arrays: Image Manipulation Project
In this project, you will be creating an application which is able to modify
images as well as create new images using 2D arrays! The first section covers
stretching the image horizontally, shrinking the image vertically, negating the
color, applying a color filter, and inverting the image. The second section
covers creating an image consisting of random pixels, placing a rectangle in
the image, and using the method to randomly place many rectangles in the
image.
Images consist of pixels which are the individual points in the image
containing some color. Each pixel has some red, green, blue, and alpha value
which represents the amount of each of those colors in the pixel. The red,
green, and blue values can be mixed to create all of the visible colors on your
screen. The alpha value represents the transparency of the pixel (or how close
the color of the pixel is to the background color of the image). A higher
resolution image means that there are more pixels contained within it.
Tasks
64/64 Complete
Mark the tasks as complete by checking them off
Provided Method Details
1.
The first two sections of this project have you investigating the code that we
have provided for you. You won’t need to write any code, but it’s important to
understand the input and output of each of these methods.
There are four utility methods provided for you. The first method
called imgToTwoD() accepts a String which can be a file path or image URL. It
returns a 2D array of integers that contains every pixel from the image stored
as int hexadecimal values containing the RGBA values for the pixel. Take a
look at how the method works in the code editor. In the main() method, we
can load image data into a 2D array of ints using the imgToTwoD() method.
Note that you can use one of the provided images or load one from a URL.
We’ll use this method to create images after we modify the 2D array of ints.
After looking at the output, feel free to re-comment this line of code to help
clean up your output for the rest of the project.
Example Method Walkthrough
6.
To start this project, we will look at an example of how to load, manipulate,
and save an image step-by-step with provided code. We will look at
the trimBorders() method. This method accepts a 2D array of int pixel data
and the number of pixels to trim off of the borders of the image. It returns the
modified image 2D array. Start by scrolling to where this method is defined in
the project code.
7.
Try looking through the method and following along with the code. Look at
how a portion of the original image is copied over to the new modified image.
The input of this method is a 2D array containing the input image data and
the output of this method is a new 2D array representing the modified image.
A detailed description of this method is in the hint for this task.
The main takeaways are that given a 2D array of ints, we make a new 2D array,
and fill that array with some values from the given array. There’s some fancy
math to make sure we fill the new array with the correct values, but the
essential thing you should focus on is the fact that given a 2D array, we return
a new 2D array.
Stuck? Get a hint
8.
Once we have completed iterating, we return the modified image data. Now
scroll back to the main() method in the code.
27.
Begin by creating a new 2D array which is the same size as the input image.
28.
Next, iterate through each pixel in the input image using nested for loops.
29.
Within the inner for loop, you will copy the final row position minus the
current row index and the final column position minus the column index. This
is similar logic to the negativeColor() method, but taking the negative of the
pixel positions instead of the color values. It will look something like
this: invertedImg[i][j] = imageTwoD[(imageTwoD.length-1)-i]
[(imageTwoD[i].length-1)-j];. See the image for an example of what takes
place.
In this image, the pixels are numbered to help show how they change position
when the image is inverted.
30.
Once the for loops are complete, you need to return the modified image. In
the main() method, load an image and pass it into the invertImage() method.
Save the modified image and view it in the browser.
Applying a Color Filter
31.
For this task you will implement the colorFilter() method. This method
modifies every pixel in the image by provided R, G, and B values as input
parameters. You must make sure that each color value does not leave the
range of 0-255.
This is an example of a filter where the filter was -75, 30, -30 (Meaning the
red values were decreased by 75, the green values were increased by 30, and
the blue values were decreased by 30)
32.
Begin by creating a new 2D array which is the same size as the input image.
33.
Loop through each pixel in the input image using nested for loops.
34.
For every pixel in the input image, extract the RGBA color values using the
provided method getRGBAFromPixel().
Stuck? Get a hint
35.
After retrieving the array of RGBA data, store the values of each color plus the
modifier value (which can be positive or negative).
Stuck? Get a hint
36.
For each of the new color values, test that it does not go outside of the range
0 to 255. If it is less than 0, set it equal to 0. If it is greater than 255, set it equal
to 255.
Stuck? Get a hint
37.
Set the values in the RGBA array to equal the new color values which you
calculated.
Stuck? Get a hint
38.
Convert the RGBA array to a single int containing the hexadecimal pixel data
using the provided method getColorIntValFromRGBA() and store it in the new
image.
Stuck? Get a hint
39.
Once the for loops are complete, you need to return the modified image. In
the main() method, load an image and pass it into the colorFilter() method
along with modifier values for red, green, and blue. Save the modified image
and view it in the browser.
Further Challenges: Painting an Image of Random
Colors
40.
Good Job! You have finished the image processing application! You have seen
how images can be converted to 2D arrays of pixels in order to modify them.
You got to write methods that manipulate images. Feel free to keep adding to,
and experimenting with, your image processing application!
In the next sections, we dive into how to use the Random class to paint random
shapes on your images. Consider these sections to be further challenges — if
you’re looking for more practice with 2D arrays, these may prove to be
interesting challenges, but if you’re feeling worn out, this is a good time to
take a break or move on to the next lesson!
Learn
2D ARRAYS: JAVA
Declaration, Initialization, and Assignment
When declaring 2D arrays, the format is similar to normal, one-dimensional arrays, except that
you include an extra set of brackets after the data type. In this example, int represents the data
type, the first set of brackets [] represent an array, and the second set of brackets [] represent
that we are declaring an array of arrays.
int[][] intTwoDArray;
You can think of this as creating an array ([]) of int arrays (int[]). So we end up with int[][].
Now that we’ve declared a 2D array, let’s look at how to initialize it with starting values. When
initializing arrays, we define their size. Initializing a 2D array is different because, instead of
only including the number of elements in the array, you also indicate how many elements are
going to be in the sub-arrays. This can also be thought of as the number of rows and columns in
the 2D matrix.
int[][] intArray1;
intArray1 = new int[row][column];
Here is an example of initializing an empty 2D array with 3 rows and 5 columns.
int[][] intArray2;
intArray2 = new int[3][5];
This results in a matrix which looks like this:
If you already know what values are going to be in the 2D array, you can initialize it and write
all of the values into it at once. We can accomplish this through initializer lists
In Java, initializer lists are a way of initializing arrays and assigning values to them at the
same time
We can use this for 2D arrays as well by creating an initializer list of initializer lists
There are three situations in which we can use initializer lists for 2D arrays:
1. In the case where the variable has not yet been declared, we can provide an abbreviated
form since Java will infer the data type of the values in the initializer lists:
2. If the variable has already been declared, you can initialize it by creating a new 2D array
object with the initializer list values:
String[][] stringValues;
stringValues = new String[][] {{"working", "with"}, {"2D",
"arrays"}, {"is", "fun"}};
3. The previous method also applies to assigning a new 2D array to an existing 2D array
stored in a variable.
In the next exercise, we’ll look at how to assign values of individual elements.
Instructions
1.
Declare a 2D array of float values called floatTwoD.
Checkpoint 2 Passed
float[][] floatTwoD;
// Initialize the 2d array from the last step to an empty 2d array consisting of 4 arrays
with 10 elements each
// Create a 2D char array called ticTacToe representing the provided tic-tac-toe board
using initializer lists. Use the characters 'X', 'O', and ' '.
char[][] ticTacToe = {{'X', 'O', 'O'}, {'O', 'X', ' '}, {'X', ' ', 'X'}};
// When no one is looking, you want to modify the game to where you, 'O', wins the
game. Replace the game board so that all X’s are O’s and all O’s are X’s. Do this in one line with
initializer lists.
ticTacToe = new char[][] {{'O', 'X', 'X'}, {'X', 'O', ' '}, {'O', ' ', 'O'}};
}
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
Accessing Elements in a 2D Array
Let’s first review how to access elements in regular arrays.
For a normal array, all we need to provide is an index (starting at 0) which represents the position
of the element we want to access. Let’s look at an example!
The first way of thinking is that the first value represents a row and the second value
represents a column in the matrix
The second way of thinking is that the first value represents which subarray to access
from the main array and the second value represents which element of the subarray is
accessed
The above example of the 2D array called data can be visualized like so. The indices are labeled
outside of the matrix:
Using this knowledge, we now know that the result of int stored = data[0][2]; would store the
integer 6. This is because the value 6 is located on the first row (index 0) and the third column
(index 2). Here is a template which can be used for accessing elements in 2D arrays:
Instructions
1.
Access the integer at the first row and fourth column of intMatrix and store it in a variable
called retrievedInt.
int[][] intMatrix = {
{1, 1, 1, 1, 1},
{2, 4, 6, 8, 0},
{9, 8, 7, 6, 5}
};
// Access the integer at the first row and fourth column of intMatrix and store it in a
variable called retrievedInt
// Print 3 times the center value of intMatrix to the console. Make sure to access the
correct element!
System.out.println(intMatrix[1][2] * 3);
}
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
Modifying Elements in a 2D Array
Now let’s review how to modify elements in a normal array.
For a one dimensional array, you provide the index of the element which you want to modify
within a set of brackets next to the variable name and set it equal to an acceptable value:
storedArray[5] = 10;
For 2D arrays, the format is similar, but we will provide the outer array index in the first set of
brackets and the subarray index in the second set of brackets. We can also think of it as
providing the row in the first set of brackets and the column index in the second set of brackets if
we were to visualize the 2D array as a rectangular matrix:
twoDArray[1][3] = 150;
To assign a new value to a certain element, make sure that the new value you are using is either
of the same type or is castable to the type already in the 2D array.
Let’s say we wanted to replace four values from a new 2D array called intTwoD. Look at this
example code to see how to pick individual elements and assign new values to them.
intTwoD[3][2] = 16;
intTwoD[0][0] = 4;
intTwoD[2][1] = 12;
intTwoD[1][1] = 8;
Here is a before and after image showing when the 2D array was first initialized compared to
when the four elements were accessed and modified.
Instructions
1.
Replace the number 4 in intMatrix with the number 0.
Again, feel free to print the matrix to confirm you changed the correct number. To print a 2D
array, use
System.out.println(Arrays.deepToString(intMatrix));
Checkpoint 2 Passed
import java.util.Arrays;
int[][] intMatrix = {
{1, 1, 1, 1, 1},
{2, 4, 6, 8, 0},
{9, 8, 7, 6, 5}
};
intMatrix[1][1] = 0;
// Declare and initialize a new empty 2x2 integer 2D array called subMatrix
int[][] subMatrix = new int[2][2];
// Using 4 lines of code, multiply each of the elements in the 2x2 top left corner of
intMatrix by 5 and store the results in the subMatrix you created. Afterwards, uncomment the
provided print statement below.
subMatrix[0][0] = intMatrix[0][0] * 5;
subMatrix[0][1] = intMatrix[0][1] * 5;
subMatrix[1][0] = intMatrix[1][0] * 5;
subMatrix[1][1] = intMatrix[1][1] * 5;
System.out.println(Arrays.deepToString(subMatrix));
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
Review of Nested Loops
We’re about to look at how we can use loops to make our lives easier when working with 2D
arrays. But before we do that, let’s take a moment to refresh ourselves on how nested loops
work.
Nested loops consist of two or more loops placed within each other. We will be looking at one
loop nested within another for 2D traversal.
The way it works is that, for every iteration of the outer loop, the inner loop finishes all of its
iterations.
This is an important concept for 2D array traversal, because for every row in a two dimensional
matrix, we want to iterate through every column. We will look more at this in the next exercise.
Nested loops can consist of any type of loop and with any combination of loops. Let’s take a
look at a few more interesting examples.
while(outerCounter<7){
System.out.println();
for(int number : innerArray){
System.out.print(number * outerCounter + " ");
}
outerCounter++;
}
The output of the above example creates a multiplication table:
0 0 0 0 0
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
6 12 18 24 30
This is an interesting example, because for every iteration of the while loop, we iterate through
every element of an array using an enhanced for loop. This is similar to the iteration pattern we
use for 2D array traversal. We will be going over that in the next exercise.
You are in charge of controlling the amount of people who reserve seats for the world famous
programming contest. You have two long arrays of integers which represent the contestant’s IDs
for two days of the competition. The index of the array represents their seat number. You need to
use nested for loops to find if a contestant tried to register for both days. Print out the ID of the
contestants who tried to register twice as well as their seat numbers for both days.
Instructions
1.
Fix the outer loop header to iterate through the first array of seats.
Checkpoint 2 Passed
Hint
For array traversal, remember to use the format: for(int iterator = 0; iterator <
array.length; iterator++) .
Be careful to fix the iterator! If you leave it as -- it’s pretty easy to create a loop that will never
end and you’ll need to refresh the page after running your code.
2.
Fix the inner loop header to iterate through the second array of seats.
Checkpoint 3 Passed
Hint
For array traversal, remember to use the format: for(int iterator = 0; iterator <
array.length; iterator++) .
3.
Replace 1==2 with conditional logic to check if an element in the first array matches an element
in the second array.
Checkpoint 4 Passed
Hint
Use array[index] == array2[otherIn
Nested.java
int matchCounter = 0;
// Fix the outer loop header to iterate through the first array of seats
// Fix the inner loop header to iterate through the second array of seats
if(seatsDayOne[i] == seatsDayTwo[j]) {
matchCounter++;
break;
}
}
int[][] intMatrix = {
};
// Store the length of the subarrays using the first subarray in intMatrix. Store it in a
variable called subArrayLength.
// Replace the outer and inner for loop headers to iterate through the entire 2D array.
Use the iterators `i` for the outer loop and `j` for the inner loop.
int sum = 0;
sum+=intMatrix[i][j];
System.out.println(sum);
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
Traversing 2D Arrays: Practice with Loops
We have seen how to traverse 2D arrays using standard for loops, but in this exercise, we will
practice traversing them using some other loop types. For example, you may want to only
retrieve elements without keeping track of the indices using enhanced for loops, or you could
continuously update the 2D array until a condition is met using while loops.
In enhanced for loops, each element is iterated through until the end of the array. When we think
about the structure of 2D arrays in Java (arrays of array objects) then we know that the outer
enhanced for loop elements are going to be arrays.
char[][] charData = {{'a', 'b', 'c', 'd', 'e', 'f'},{'g', 'h', 'i',
'j', 'k', 'l'}};
Print out every character using enhanced for loops:
a b c d e f
g h i j k l
Notice how we can use different loop types for traversal, but still receive the same result.
Instructions
1.
Use nested enhanced for loops to calculate the total number of characters in the wordData 2D
array and print the result to the console. (Get the string .length() of each element)
Checkpoint 2 Passed
Hint
Make sure to look at each array in the outer nested for loop for(String[] wordRow :
wordData) and then each string within the subarray in the inner loop for(String word : wordRow).
2.
Using nested while loops, iterate through all of the elements in the 2D array and print them to the
console using the format: word [row][column]. The print statement has been provided (you will
need to modify it if you use iterators other than i and j).
Checkpoint 3 Passed
Hint
Remember to check the iterators in the while loop headers and to manually increment the
iterators at the end of each loop. The inner while loop’s iterator should be set to 0 again before
entering the inner while loop. The provided print statement should be placed in the
inner while loop. The print statement also assumes that you are using the iterators i and j.
//Use nested enhanced for loops to calculate the total number of characters in the
wordData 2D array and print the result to the console. (Get the string .length() of each element)
int characterCount = 0;
for(String s : stringRow) {
characterCount += s.length();
System.out.println(characterCount);
//Using nested while loops, iterate through all of the elements in the 2D array and
print them to the console using the format: word [row][column]. The print statement has been
provided.
int i = 0, j = 0;
while(i<wordData.length) {
j=0;
while(j<wordData[i].length) {
j++;
i++;
}
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
Traversing 2D Arrays: Row-Major Order
Row-major order for 2D arrays refers to a traversal path which moves horizontally through each
row starting at the first row and ending with the last.
Although we have already looked at how 2D array objects are stored in Java, this ordering
system conceptualizes the 2D array into a rectangular matrix and starts the traversal at the top
left element and ends at the bottom right element.
Let’s take a closer look at the structure of the nested for loops when traversing a 2D array:
The step value increases with every iteration within the inner for loop. Because of this, we can
see the order in which each element is accessed. If we follow the step value in the output shows
us that the elements are accessed in the same order as the row-major diagram above. Now why is
that?
This is because in our for loop, we are using the number of rows as the termination condition
within the outer for loop header a < matrix.length; Additionally, we are using the number of
columns b < matrix[a].length as the termination condition for our inner loop. Logically we are
saying: “For every row in our matrix, iterate through every single column before moving to the
next row”. This is why our above example is traversing the 2D array using row-major order.
Here is a diagram showing which loop accesses which part of the 2D array for row-major order:
Why Use Row-Major Order?
Row-major order is important when we need to process data in our 2D array by row. You can be
provided data in a variety of formats and you may need to perform calculations of rows of data at
a time instead of individual elements. Let’s take one of our previous checkpoint exercises as an
example. You were asked to calculate the sum of the entire 2D array of integers by traversing
and accessing each element. Now, if we wanted to calculate the sum of each row, or take the
average of each row, we can use row-major order to access the data in the order that we need.
Let’s look at an example!
Instructions
1.
You are provided with some runner lap data. Take a look at the loops we’re using to iterate
through this 2D array. Replace the incorrect for loop headers to perform row-major traversal.
Use the iterators outer and inner for the outer and inner loops.
Checkpoint 2 Passed
Hint
Row-major order uses the length of the 2D array as the terminating condition for the outer loop
and the length of a subarray as the termination condition of the inner loop.
2.
Enter the missing line of code within the nested for loop to sum up the values for each row in the
runner data.
We’ve already created a variable named runnerTime that you can use to sum these values.
Checkpoint 3 Passed
Hint
Use the 2D array accessor: twoDArray[row][column]. Add that value to runnerTime using +=.
3.
We’ve given you a variable named averageVal that currently stores 0. Edit that line of code to
find the average time of each runner.
Checkpoint 4 Passed
Hint
Divide the result by the length of the subarray.
double[][] times = {{64.791, 75.972, 68.950, 79.039, 73.006, 74.157}, {67.768, 69.334,
70.450, 67.667, 75.686, 76.298}, {72.653, 77.649, 74.245, 62.121, 63.379, 79.354}};
// Replace the incorrect for loop headers, use the iterators 'outer' and 'inner' for the
outer and inner loops
runnerTime = 0.0;
// Enter the missing line of code to sum up the values in each row. Use
the variable runnerTime
runnerTime+=times[outer][inner];
}
// Enter the missing line of code to find the average time of each runner. Use
the variable averageVal
double averageVal = 0;
}
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
Traversing 2D Arrays: Column-Major Order
Column-major order for 2D arrays refers to a traversal path which moves vertically down each
column starting at the first column and ending with the last.
This ordering system also conceptualizes the 2D array into a rectangular matrix and starts the
traversal at the top left element and ends at the bottom right element. Column-major order has
the same starting and finishing point as row-major order, but it’s traversal is completely different
Let’s look at our example 2D array from the last exercise and see what needs to be changed.
Here is a diagram showing which loop accesses which part of the 2D array for column-major
order:
Why Use Column-Major Order?
Column major order is important because there are a lot of cases when you need to process data
vertically. Let’s say that we have a chart of information which includes temperature data about
each day. The top of each column is labeled with a day, and each row represents an hour. In
order to find the average temperature per day, we would need to traverse the data vertically since
each column represents a day. As mentioned in the last exercise, data can be provided in many
different formats and shapes and you will need to know how to traverse it accordingly.
Let’s look at our sum example from the last exercise, but now using column-major order.
We will be using the same runner data from the last exercise, but this time we are going to take
the average times per lap rather than per runner. This requires that we use column-major
traversal.
Instructions
1.
You are provided with some runner lap data. Take a look at the loops we’re using to iterate
through this 2D array. Replace the incorrect for loop headers to perform column-major traversal.
Use the iterators outer and inner for the outer and inner loops.
Hint
Remember that we flip the outer and inner loop terminating conditions for column-major order
as well as the indices in the accessors.
2.
Enter the missing line of code within the nested for loop to sum up the values for each column in
the runner data.
We’ve already created a variable named lapTime that you can use to sum these values.
Hint
Use the 2D array accessor: twoDArray[row][column]. Add that value to lapTime using +=.
Remember that the iterators in column-major order need to be flipped since the direction we are
traversing has flipped — the inner for loop variable controls the rows and the outer for loop
variable controls the columns.
3.
We’ve given you a variable named averageVal that currently stores 0. Edit that line of code to
find the average time of each lap.
Hint
Remember to flip the order of the iterators, since we have flipped the direction we are traversing.
Columnmajor.java
double[][] times = {{64.791, 75.972, 68.950, 79.039, 73.006, 74.157}, {67.768, 69.334,
70.450, 67.667, 75.686, 76.298}, {72.653, 77.649, 74.245, 62.121, 63.379, 79.354}};
// Replace the incorrect for loop headers, use the iterators 'outer' and 'inner' for the
outer and inner loops
lapTime = 0.0;
// Enter the missing line of code to sum up the values in each row. Use
the variable lapTime
lapTime+=times[inner][outer];
}
// Enter the missing line of code to find the average time of each lap. Use the
variable averageVal
double averageVal = 0;
}
My Home
Course Menu
Connected to Codecademy
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
Combining Traversal and Conditional Logic
When working with 2D arrays, it is important to be able to combine traversal logic with
conditional logic in order to effectively navigate and process the data. Here are a few ways in
how conditional logic can affect 2D array traversal:
First, let’s think about a situation where you have some string data inside a 2D array. We have an
application which allows users to input events on a calendar. This is represented by a 5x7 2D
array of strings. Due to the fact that the number of days in each month is slightly different and
that there are less than 35 days in a month, we know that some of our elements are going to be
empty. We want our application to do a few things:
Detect which days of which weeks have something planned and alert us about the event.
Count the number of events for each week
Count the number of events for each day
Here is a visualization of what our calendar data looks like after a user has entered in some event
information:
Here’s what our calendar data looks like in our application
Let’s take care of the first 2 requirements in one set of nested row-major loops
Additionally, we can use conditional logic to skip portions of the 2D array. For example, let’s
say we wanted to print the events for weekdays only and skip the weekends.
We could use a conditional statement such as if(j!=0 && j!=6) in order to skip Sunday (0) and
Saturday (6).
These modifications to our 2D array traversal are very common when processing data in
applications. We need to know which cells to look at (skipping column titles for example), which
cells to ignore (empty data, invalid data, outliers, etc.), and which cells to convert (converting
string input from a file to numbers).
We are making a simple grayscale image editor program and we want to apply some
modifications to the image. We have a 4x8 pixel image that is stored as a 2D array of integers.
The integer value represents the brightness of the pixel, where the acceptable values are
between 0 and 255, inclusive.
Instructions
1.
First, we want to crop the image down to a 4x6 image, removing the right 2 columns. Declare
and initialize a new 2D array of integers with 4 rows and 6 columns called newImage.
Hint
Remember to create a new 2D array using this format: datatype[][] variableName = new
datatype[rows][columns];.
2.
Now that you have your empty image, use nested for loops to copy over the data from the
original image (stored in imageData) to the new image, make sure not to include the cropped out
columns (right 2 columns).
Hint
To copy over the values, use: new2DArray[row][col] = old2DArray[row][col].
3.
You want to decrease the brightness of the new image by 50 units. The way this works is that for
every integer in the new 2D array, we will subtract the value by 50. Remember that the value
range for the pixel is 0-255, so if the result tries to go below 0, just set it equal to 0.
Hint
Remember to check if the value minus 50 is less than 0 when iterating through the elements of
the new image: if(newImage[row][column]-50<0). If that condition is true, then set the element to
equal 0 else subtract 50 from the element.
import java.util.Arrays;
int[][] imageData={{100,90,255,80,70,255,60,50},
{255,10,5,255,10,5,255,255},
{255,255,255,0,255,255,255,75},
{255,60,30,0,30,60,255,255}};
//First, we want to crop the image down to a 4x6 image, removing the right 2
columns. Declare and initialize a new 2D array of integers with 4 rows and 6 columns called
`newImage`.
//Now that you have your empty image, use nested **for** loops to copy over the
data from the original image to the new image, make sure not to include the cropped out columns.
newImage[i][j] = imageData[i][j];
System.out.println(Arrays.deepToString(newImage));
//You want to decrease the brightness of the new image by 50 units. The way this
works is that for every integer in the new 2D array, we will subtract the value by 50. Remember that
the value range for the pixel is 0-255, so if the result tries to go below 0, just set it equal to 0.
if(newImage[i][j]-50<0){
newImage[i][j] = 0;
else{
newImage[i][j]-=50;
System.out.println(Arrays.deepToString(newImage));
}
My Home
Course Menu
Workspace restored.
Get Unstuck
Tools
Learn
2D ARRAYS: JAVA
2D Array Review
Let’s review the concepts we have learned throughout this lesson.
Arrays are objects in Java, we can have arrays of objects, therefore we can also have arrays of
arrays. This is the way 2D arrays are structured in Java.
We can declare and initialize 2D arrays in a few different ways depending on the situation:
We can also think of them as the index of the outer array and the index of the subarray
We can modify elements the same way letters[1][2] = 'z';
We can use loops of any type, but we typically use nested for loops to keep track of the
indices
Row-major order traverses through each row moving horizontally to the right through
each row
Column-major order traverses through each column moving vertically down through each
column
Row-major order and column-major order start and end on the same elements, but the
paths are different.
In order to convert row-major to column-major, we need to make the outer loop
terminating condition depend on the number of columns, make the inner loop terminating
condition depend on the number of rows, and flip the variables in our accessor within the
inner loop to ensure that we don’t try to access outside of the 2D array since we flipped
the direction of traversal.
// Row-major order
for(int o = 0; o < letters.length; o++) {
for(int i = 0; i < letters[o].length; i++) {
char c = letters[o][i];
}
}
// Column-major order
for(int o = 0; o < letters[0].length; o++) {
for(int i = 0; i < letters.length; i++) {
char c = letters[i][o];
}
}
Conditional logic in our 2D array traversal allows us to use the data in a meaningful way. We
can control which rows and columns we look at, ensure that the data we are looking at is what
we want, perform calculations on specific elements, avoid throwing exceptions, and more.
System.out.println("After...");
System.out.println(Arrays.deepToString(words).replace("],", "],\n")
+ "\n");
Here is the output of the above code:
Before...
[[championship, QUANTITY, month],
[EMPLOYEE, queen, understanding],
[method, writer, MOVIE]]
After...
[[CHAMPIONSHIP, quantity, MONTH],
[employee, QUEEN, UNDERSTANDING],
[METHOD, WRITER, movie]]
Time to work some review problems!
After learning about 2D arrays, you have decided to become a CS professor and you are now
teaching your class about 2D arrays. You are making an application which will keep track of
their exam grades and show you statistics about their performance. You will be using 2D arrays
to keep track of their exam grades
Instructions
1.
First, declare and initialize a 4x3 2D array of doubles called scores which will contain the exam
data for four students. The rows will represent the student and the columns will represent the
exam number. You already know the first exam scores (80.4, 96.2, 100.0, 78.9). Use initializer
lists to store the first exam scores in the first column and -1 for the remaining exams. Use the
provided print statement to print the result in the console.
Checkpoint 2 Passed
Hint
Remember to use nested initializer lists like so: datatype[][] variable = {{val1, val2, val3},
{val4, val5, val6}, {val7, val8, val9}};.
2.
The next set of exams have occurred. Using 4 lines of code, manually enter the scores (89.7,
90.5, 93.6, 88.1) for the second exam (column 1). Use the provided print statement to print the
updated 2D array as well.
Checkpoint 3 Passed
Hint
Remember to access and modify elements using: twoDArray[row][col] = val;.
3.
You have realized that you will only be keeping track of 2 exam grades instead of 3. Declare and
initialize an empty 4x2 2D array of double values called newScores.
Checkpoint 4 Passed
Hint
Declare and initialize an empty 2D array like so: datatype[][] variable = new datatype[row]
[col];.
4.
Using loops, copy all of the scores for exam 1 and 2 into the new 2D array. (Do not include the
-1 values)
Checkpoint 5 Passed
Hint
Remember to copy values over using: twoDArrayOne[i][j] = twoDArrayTwo[i][j]; when in a
nested loop.
5.
You have allowed the students to complete an extra credit activity to contribute towards their
scores. For all exam grades less than 90, add 2 additional points to the grade in newScores.
Checkpoint 6 Passed
Hint
Remember to test the elements to see if they are under 90: if(newScores[row][column]<90). If the
condition is true then increase the element by 2.
Review.java
import java.util.Arrays;
//First, declare and initialize a 4x3 2D array of doubles called `scores` which will contain the exam
data for four students. The rows will represent the student and the columns will represent the exam
number. You already know the first exam scores (80.4, 96.2, 100.0, 78.9). Use initializer lists to store
the first exam scores in the first column and -1 for the remaining exams. Use the provided print
statement to print the result in the console.
double[][] scores = {{80.4, -1, -1}, {96.2, -1, -1}, {100.0, -1, -1}, {78.9, -1, -1}} ;
System.out.println(Arrays.deepToString(scores));
//The next set of exams have occurred. Using 4 lines of code, manually enter the scores (89.7, 90.5,
93.6, 88.1) for the second exam (column 1). Use the provided print statement to print the updated 2D
array as well.
scores[0][1] = 89.7;
scores[1][1] = 90.5;
scores[2][1] = 93.6;
scores[3][1] = 88.1;
System.out.println(Arrays.deepToString(scores));
//You have realized that you will only be keeping track of 2 exam grades instead of 3. Declare and
initialize an empty 4x2 2D array of double values called newScores
//Using loops, copy all of the scores for exam 1 and 2 into the new 2D array. (do not include the -1
values)
newScores[i][j] = scores[i][j];
}
System.out.println(Arrays.deepToString(newScores));
//You have allowed the students to complete an extra credit activity to contribute towards their
scores. For all exam grades less than 90, add 2 additional points to the grade in `newScores`
if(newScores[i][j]<90){
newScores[i][j]+=2;
System.out.println(Arrays.deepToString(newScores));
}
https://curl.se/
https://www.codecademy.com/paths/create-rest-apis-with-spring-and-java/tracks/spring-apis-web-
and-spring-basics/modules/how-spring-works/articles/what-is-curl-article
https://developer.android.com/studio/intro