Presentation is loading. Please wait.

Presentation is loading. Please wait.

Object Comparisons and Arrays

Similar presentations


Presentation on theme: "Object Comparisons and Arrays"— Presentation transcript:

1 Object Comparisons and Arrays
Phil Tayco San Jose City College Slide version 1.3 Updated Sep. 29, 2019

2 Arrays Revisited Recall how Java arrays are created
int[] numbers; This is a variable declaration of an integer array called numbers When we look under the hood, numbers is also just a reference and in this case, the memory for the array is not yet allocated We have to define how many integers we want to reserve for the array to allocate memory numbers ?

3 Arrays Revisited This reserves 10 integers in memory
numbers = new int[10]; This reserves 10 integers in memory In Java, since the type of the array elements is simple, they are initialized with a given value of 0 Notice how the memory allocation is done using the “new” keyword. It’s the same notation as creating an object Arrays are data structures that can also be treated like a class numbers 0x3320aad2 1 2 9

4 Array Length A good example of an Array used like a class is the “.length” property in Java int[] numbers = new int[10]; for (c = 0; c < numbers.length; c++) System.out.println(numbers[c]); .length is a special property for all Arrays that return the capacity of the Array The property is public. It is considered okay to be public because it is a fixed value once you allocate memory for an Array In this example, numbers.length has a value of 10

5 Fun With Arrays In the next example, let’s start things off by modeling a Time class public class Time { private int hours; private int minutes; private int seconds; } The corresponding constructor(s), set/get, and toString methods should more easily be something you can define now What are some predicate methods we could add?

6 Fun With Arrays Back to arrays. Recall its definition:
An ordered set of elements referred to by the same variable name with each element accessed by an index Each element is the same data type The second point is of most significance with classes because remember what a class is: it’s a complex data type! Just like you can create an array of integers, now you can also create an array of classes… Time[] alarms = new Time[10]; Arrays of objects need to be treated with care but as seen with other examples, even though the complexity increases, the pattern of use is consistent

7 Arrays Step By Step Time[] alarms; As with an Array with simple data types, the declaration of alarms here is only creating the reference with no memory allocated When we are ready to allocate memory for the alarms Array, we state the number of Time elements to reserve What will the array elements actually look like? What will the array elements be initialized to? alarms ?

8 Arrays Step By Step This will reserve 10 Time references in memory
alarms = new Time[10]; This will reserve 10 Time references in memory At this point, each Time element has no memory allocated. Only references are created Important distinction to make is that we’ve created memory for the array, but each element does not have an actual Time object yet Any element can have a Time object created at any time but note that also means until that point, the element is pointing to null alarms 0x2d2a1100 ? ? ? ? 1 2 9

9 Arrays Step By Step alarms[0] = new Time(); alarms[1] = new Time(6, 0, 0); This creates 2 Time objects in the first 2 elements of the alarms array Lots of observations to make with this configuration alarms 0x2d2a1100 0x17f32a20 0x44a059f2 ? ? 1 2 9 6

10 Arrays of Objects Once an element of alarms is instantiated, treatment of the object is as normal with the proper Array notation alarms[0].setHours(5); Array elements are instantiated as normal objects such as using the default constructor or any other overloaded one

11 Arrays of Objects Array elements are references so you can set one element equal to another (to be used with care!) alarms[2] = alarms[0]; alarms 0x2d2a1100 0x17f32a20 0x44a059f2 0x17f32a20 1 2 6

12 Arrays of Objects The most common error to make with Arrays of objects is to attempt to use member functions for elements that have not yet been instantiated for(int c = 0; c < alarms.length; c++) System.out.println(alarms[c]); The problem here is that alarms.length returns the capacity of the array and not the actual number of elements that have been instantiated In this example, alarms.length is 10. If only 3 objects have been instantiated, the other 7 will have null values Accessing a member function of a null object in Java results in a “NullPointerException” – a very common run-time error!

13 Arrays of Objects How best to deal with this is to maintain a numberOfAlarms variable for how many Time objects in the alarms have been instantiated Time[] alarms = new Time[10]; alarms[0] = new Time(); alarms[1] = new Time(6, 0); int numberOfActiveAlarms = 2; for(int c = 0; c < numberOfActiveAlarms; c++) System.out.println(alarms[c]); This also means you must maintain numberOfAlarms appropriately (instantiations and deletions) as well as the array contents (no “gaps” in the array)

14 Exercise 6 In your main program from Exercise 5, add the following exactly in this order Create an array of Color objects called “crayons” with a maximum capacity of 10 colors Instantiate 4 different color objects in the crayons array, you can choose any color object values you like Write a loop that prints the 4 Color objects in the array and uses the Color’s toString function for each object Next, add 2 more Color objects to the array and then print the 6 Color objects from the array You can write a function that prints the Color objects in the array. This is not required for this exercise, but it may be good practice to try as it will help with Exercise 7

15 Composition with Arrays
Recall the definition of designing classes with Composition – you can have a class with a property that is another class Since Arrays are classes, it is possible to create a property that is an Array public class Clock { private Time currentTime; private int numberOfAlarms; private Time[] alarms; } This is a powerful class design incorporating what we’ve learned that sets up the foundation for advanced OO concepts later on

16 Composition with Arrays
To learn this type of design, maintain the design processes of what we’ve learned so far Start with the default constructor public Clock() { currentTime = new Time(); numberOfAlarms = 0; alarms = new Time[10]; } numberOfAlarms is simple and currentTime is an object instantiated with the Time default For the alarms array, all we did here is allocate the size of the alarms. What would a Clock object now look like?

17 Composition with Arrays
Clock myClock = new Clock(); Each Time object alarms in the alarms array has is null. How would we manage Time object allocation? myClock 0x553f12f0 currentTime 0x1122abd0 numberOfAlarms alarms 0x73221ac4 hours minutes ? ? ? ? seconds 1 2 9

18 Composition with Arrays
We could instantiate all 10 Time objects in the alarms array in the default constructor public Clock() { currentTime = new Time(); numberOfAlarms = 0; alarms = new Time[10]; for (int c = 0; c < alarms.length; c++) alarms[c] = new Time(); } What would a Clock object now look like? What are pros/cons with this?

19 Composition with Arrays
Clock myClock = new Clock(); myClock 0x553f12f0 currentTime 0x1122abd0 numberOfAlarms alarms 0x73221ac4 0x2233… 0x241a… hours 1 minutes hours seconds minutes seconds

20 Composition with Arrays
Benefits are that we are guaranteed at least an object in every Time Array element (reduced chance of NullPointerException at run-time) Cost is memory usage as you may have a Clock object needing only 2 alarms The “numberOfAlarms” property also does not align with the number of active Time objects in the alarms array (it is correct conceptually, but not physically) Guideline is the first approach. In the constructors, only allocate the size of the array for the property Use other methods to instantiate objects for the array as you need them (more on that later)

21 Composition with Arrays
Following the guideline, other constructors with class properties that are Arrays should then only focus on the capacity of the Array public Clock(Time c) { currentTime = new Time(c); numberOfAlarms = 0; alarms = new Time[10]; } You can also write constructors that take Time objects for alarm(s) Sticking with the guideline though, you would not want to allow this This forces the only way to create alarms in a Clock object through other methods…

22 Composition with Arrays
Set methods typically mean to set the value of a given property. However, alarms is an Array You can provide a method to create the alarms from a Time array as a parameter public void setAlarms(Time[] a, int n)… This requires the user of the Clock object to create a Time array and send it in as a parameter and also send in the number of Time objects active in the array (through n) While this can be done, this is a good example of putting too much on the programmer Conceptually, the method of setting an alarm is “adding” one, which we can code

23 Composition with Arrays
public void addAlarm(Time t) { } Things to keep in mind for this algorithm Adding an alarm to the clock conceptually means adding an alarm Time object to the alarms Array numberOfAlarms needs to be maintained Time object is coming in, do we want to use the reference or instantiate a copy of the object?

24 Composition with Arrays
Here, we will create a new Time object and add it to the alarms Array using the copy constructor public void addAlarm(Time t) { alarms[?] = new Time(t); } The Time object we want to add to the alarms array is instantiated through t The challenge here is that we now need to figure out where in the alarms array where the new Time object will go. What should go here?

25 Composition with Arrays
Here’s a Clock object with no alarms set. Where should the new alarm go in the alarms array? myClock 0x553f12f0 currentTime 0x1122abd0 numberOfAlarms alarms 0x73221ac4 hours minutes ? ? ? ? seconds 1 2 9

26 Composition with Arrays
The correct index element needs to be the next available spot in the Array If we design the Array such that all elements are next to each other starting at 0, then we already have a property that can also be used to identify the next available open spot in the Array public void addAlarm(Time t) { alarms[numberOfAlarms] = new Time(t); } There’s still a problem with this code though. What is it?

27 Composition with Arrays
What’s wrong with this picture? myClock 0x553f12f0 currentTime 0x1122abd0 numberOfAlarms alarms 0x73221ac4 0x2233… null hours 1 minutes hours 8 seconds minutes seconds

28 Composition with Arrays
numberOfAlarms must also be maintained. When a new alarm is added, we need to also increment numberOfAlarms public void addAlarm(Time t) { alarms[numberOfAlarms++] = new Time(t); } Notice the only way Time objects are added to the Array is through this function Since numberOfAlarms if maintained this way, we do not (and should not) have a “setNumberOfAlarms” method Control over the Array and numberOfAlarms is strong because it is managed within the class

29 Composition with Arrays
What will happen if we’re at capacity for the alarms Array? We can do a capacity check first public void addAlarm(Time t) { if (numberOfAlarms < alarms.length) alarms[numberOfAlarms++] = new Time(t); } Note that we use alarms.length instead of a fixed value of 10. Why is this good? If alarms is full, an attempt to add an alarm does nothing. Should we also print an error message to the user?

30 Composition with Arrays
What’s the problem here? public void addAlarm(Time t) { if (numberOfAlarms < 10) alarms[numberOfAlarms++] = new Time(t); else System.out.println(“Alarms is full”); } The logic handling is correct, but printing an error message assumes the program using the Clock object is interacting with the user via console For a true stand-alone class, the methods should not directly interact with the end user is a specific way like console output Question is how a capacity error is “reported”

31 Composition with Arrays
public boolean addAlarm(Time t) { if (numberOfAlarms < 10) alarms[numberOfAlarms++] = new Time(t); return true; } return false; The return value communicates back with whatever program that’s using it This model can be used with other methods and supports a tiered OO design approach Using system.out.println is still useful for debugging purposes

32 Comparing Objects If we can use a method to add an alarm, we’ll need another to remove an alarm Before looking at that though, we need to understand how to compare objects Comparing simple variables is not hard int x, y; x = 10; y = 10; if (x == y) System.out.println(“Equal variables”); What happens if we did the exact same thing with objects?

33 Comparing Objects However, this will not result in printing Equal
Time t1, t2; t1 = new Time(10, 15, 30); t2 = new Time(10, 15, 30); if (t1 == t2) System.out.println(“Equal”); However, this will not result in printing Equal It is important to see why this happens from looking at memory behind the scenes Recall that when t1 and t2 are instantiated, they are individually assigned locations in memory Even though the property values within the objects are the same, their locations are different

34 Comparing Objects The “==“ operation can only compare one value that is at the given variable locations Notice that with objects, the immediate values compared the memory addresses of t1 and t2 – this results in comparing these 2 values as not equal What we want to happen is for the property values of these objects to be compared Since classes are complex data types, we have to define how that comparison occurs t1 0x4412ff20 t2 0x17dc7248 10 10 15 15 30 30

35 Comparing Objects The “equals” method is defined in the Time class
Time t1, t2; t1 = new Time(10, 15, 30); t2 = new Time(10, 15, 30); if (t1.equals(t2)) System.out.println(“Equal”); The “equals” method is defined in the Time class It is technically a predicate methodand usually takes its own class as an input parameter (i.e. the Time class “equals” method takes a Time object as input) Now we need to define the “equals” method

36 Comparing Objects public boolean equals(Time t) { if (hours != t.getHours() || (minutes != t.getMinutes() || (seconds != t.getSecondss()) return false; return true; } Here, we check to see if any of the current Time object property values does not match the given t object’s corresponding property If any mismatch, the method returns false, otherwise it will return true This implies another method that should be created when designing any class along with constructors, set/get, and toString

37 Composition with Arrays
Now that we have an idea how to compare objects, we can use that in removeAlarm public boolean removeAlarm(Time t) { } Things to keep in mind for this algorithm Needing to find the alarm in the Array from t Assuming all elements are next to each other while removing an element cannot leave a “hole” in the Array Maintaining the numberOfAlarms property Using the Boolean return type appropriately Before coding, we can tackle each of these things conceptually

38 Composition with Arrays
Here’s a Clock with 4 alarms set: hours minutes myClock 0x553f12f0 seconds currentTime 0x1122abd0 numberOfAlarms 4 alarms 0x73221ac4 0x2233… 0xa314… 0259a… 0x5bc2… null 1 2 3 4 hours 8 9 9 14 minutes 30 seconds

39 Composition with Arrays
removeAlarm algorithm: We must use a loop to go through each element of the alarms array to see if it equals the given t object If we find a match, we can remove it and return true. Otherwise, if the loop completes without a match, return false If we remove an alarm, we cannot leave a “hole” in the Array and we must maintain the numberOfAlarms property One approach is to replace the alarm object being removed with the last alarm in the array We then must also decrement numberOfAlarms by one

40 Composition with Arrays
public boolean removeAlarm(Time t) { int c = 0; while (c <= numberOfAlarms) if (alarms[c].equals(t)) alarms[c] = alarms[numberOfAlarms-1]; alarms[--numberOfAlarms] = null; return true; } c++; return false; How does this change the previous picture?

41 Composition with Arrays
Here’s a Clock with 4 alarms set: hours minutes myClock 0x553f12f0 seconds currentTime 0x1122abd0 numberOfAlarms 3 alarms 0x73221ac4 0x2233… 0x5bc2… 0259a… null null 1 2 3 3 4 hours 8 9 14 minutes 30 seconds

42 Composition with Arrays
How can this all look from the Clock object usage perspective? public static void main(String[] args) { Time now = new Time(20, 30); Clock phoneClock = new Clock(now); Time wakeupTime = new Time(6, 0); phoneClock.addAlarm(wakeupTime); Time timeToDriveToWork = new Time(8, 0); phoneClock.addAlarm(timeToDriveToWork); phoneClock.removeAlarm(wakeupTime); } Note how the code is more readable and better models the real world concepts versus using more cryptic code symbols Responsibility for defining how to add and remove an alarm is handled where it should be which is in the Clock class

43 Composition with Arrays
Consider what other methods could be useful for main to “request” of the Clock object How many alarms are currently in the Clock? Does an alarm of a specific time exist? What about other typical methods? How would you code toString in the Clock? What about the copy constructor and equals methods? This starts paving the way for larger scale applications with multiple class usage Thinking about what individual classes have and are capable of providing Thinking about how users of these classes (main or other classes) will use these objects

44 Exercise 7 Create a new project and copy your Car and Color classes from exercise 6 into it Add a ParkingLot class that has a name and can contain up to 4 Car objects Create the following methods for the ParkingLot class following the exact signatures given public ParkingLot() public boolean addCar(Car) public boolean removeCar(Car) public int getNumberOfCarsParked() public boolean carExists(Car) public String toString() Create a main program that tests creates a ParkingLot object and tests all the functions appropriately Use good test data to test all the logic of your functions

45 Exercise 7 Extra credit: Add the following methods
public ParkingLot(ParkingLot) public boolean equals(ParkingLot) public void clear() Create a main program that interactively works with the end user allowing them to do the following functions: Add car Remove car Does a certain car exist Get how many available spaces left Show all parked cars This is a significant exercise and you will be given extra time to work on this Extra credit is good practice for the final project


Download ppt "Object Comparisons and Arrays"

Similar presentations


Ads by Google