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.2 Updated Oct. 7, 2018

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 get a similar class treatment 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 because it is popular to use. It is also considered to be a fixed value as once you allocate memory for an Array, the size is fixed In this example, numbers.length has a value of 10

5 Fun With Arrays Remember the defining elements of an array:
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 Times… 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

6 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 ?

7 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

8 Arrays Step By Step alarms[0] = new Time(); alarms[1] = new Time(6, 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

9 Arrays of Objects Once an element of alarms is instantiated, treatment of the object is as normal with the proper Array notation alarms[0].setHour(5); Array elements are references so you can set one element equal to another (to be used with care!) alarms[2] = alarms[0]; Array elements are instantiated as normal objects such as using the default constructor or any other overloaded one

10 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 2 objects have been instantiated, the other 8 will have null values Accessing a member function of a null object in Java results in a “NullPointerException” – a very common run-time error!

11 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 numberOfAlarms = 2; for(int c = 0; c < numberOfAlarms; 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)

12 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 all of what we’ve learned that sets up the foundation for advanced OO concepts later on

13 Composition with Arrays
As with other concepts going from simple to complex, maintain the design patterns Start with the constructors. What would the default look like? public Clock() { currentTime = new Time(); numberOfAlarms = 0; alarms = new Time[10]; } numberOfAlarms and currentTime are simpler design decisions for their default values For the alarms array, all we did here is allocate the size of the alarms. No elements are instantiated. Could we have? Should we?

14 Composition with Arrays
If we did instantiate every Time in the alarms, we would need to create all 10 Time objects public Clock() { currentTime = new Time(); numberOfAlarms = 0; alarms = new Time[10]; for (int c = 0; c < alarms.length; c++) alarms[c] = new Time(); } Benefits here are that we are guaranteed at least an object in every Array element (reduced chance of NullPointerException at run-time) Cost is memory usage as you may have a Clock object needing only 2 Times

15 Composition with Arrays
Now the other constructors. With class properties that are Arrays, a common design decision is to only focus on the capacity of the Array and not instantiating the elements with actual data public Clock(Time c) { currentTime = new Time(c); numberOfAlarms = 0; alarms = new Time[10]; } Notice numberOfAlarms here is not set from a given input parameter Taking this approach relies on updating alarm contents by other means…

16 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)… This requires the user of the Clock object to create a Time array and send it in as a parameter The setAlarms method has to also decide how to use the Time array coming in Set alarms array equal to a? Copy construct elements of a in alarms

17 Composition with Arrays
Another way to manage Arrays as a class property is to provide an “add” method 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 Assumptions on the structure and design intent of the alarms Array Time object is coming in, do we want to use the reference or instantiate a copy of the object?

18 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); } At this point, the alarms element is instantiated from given data We can also overload addAlarm with 2 integer input parameters We’re not done though. Notice the “?” for the index element. What should go here?

19 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?

20 Composition with Arrays
numberOfAlarms must also be maintained. Since a new alarm is being added, we need to 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. Control over the Array and numberOfAlarms is strong (they are also private!) Are there other problems with this?

21 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 < 10) alarms[numberOfAlarms++] = new Time(t); } While this avoids an ArrayOutOfBounds exception, it also means if alarms is full, an attempt to add an alarm does nothing The natural response is to print an error message to the user…

22 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 a interacting with the user via console The Clock object in use here could also be part of another class through composition Question is how a capacity error is “reported”

23 Composition with Arrays
public boolean addAlarm(Time t) { if (numberOfAlarms < 10) alarms[numberOfAlarms++] = new Time(t); return true; } return false; The updated return type is how the method results communicates back with the program or class 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

24 Composition with Arrays
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

25 Composition with Arrays
public boolean removeAlarm(Time t) { int c = 0; while (c < numberOfAlarms) if (alarms[c].equals(t)) << remove alarm code >> numberOfAlarms--; return true; } c++; return false; Needing to find the alarm in the Array from t Removing an element cannot leave a “hole” in the Array Maintaining the numberOfAlarms property Using the Boolean return type appropriately

26 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; Assuming the order of the alarms does not matter (the alarms are not sorted in the Clock), we can replace the alarm to remove with the last alarm in the Array This prevents holes from forming in the Array after an alarm is removed

27 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 reflects the design thoughts and captures in terms that look less cryptic

28 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? How do you print a Clock as a String? How do the copy constructor and equals methods work? 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 These uses are captured in the Application Programmer’s Interface (API) which acts like a contract document showing what the class will provide and what is needed when used

29 Composition with Arrays
The API can be defined using the function signatures to show what is available public Clock() public Clock(Time) public Clock(Clock) public void setCurrentTime(Time) public void setCurrentTime(int, int) public Time getCurrentTime() public int getNumberOfAlarms() public Time[] getAllAlarms() public boolean addAlarm(Time) public boolean addAlarm(int, int) public boolean removeAlarm(Time) public boolean removeAlarm(int, int) public boolean equals(Clock) public Time findAlarm(int, int) public Time getAlarm(int) public boolean isAlarmTriggered(int, int) public String toString()

30 Composition with Arrays
Based on these signatures alone, a class programmer can start formulating ideas on how to code these Documentation can be done with comments in the code that can be published later Documentation also helps define assumptions to allow for parallel development to occur All programming languages APIs follow this format, shaping your thinking as to how to code and reuse

31 Exercise 4 Part one: Design a new Block class reusing your existing House, Address and ZipCode classes from previous programming exercises - a Block contains up 20 Houses Create only the function signatures you think would be needed for the Block class – this includes the standard suggested methods (constructors, set/get, toString, equals, add/remove) plus others you think would make sense for a Block You can write the function signatures in code, but the function bodies should be empty – you can write enough code so that it compiles with a test program, but the most code in the bodies should be return statements You can also write API documentation of the functions in the code using comments (if you’re using Java, you can take a look at what javadoc uses) Show your design to me before proceeding to part two

32 Exercise 4 Part two: After getting approval for your design, write the code for the functions I approve you to do Create a main test program that focuses only on the Block class methods – all Block methods must be called and tested Remember the Block class will be reusing House, Address and ZipCode classes - these will need to be in your overall test project, but they do not need to be individually tested (since they should be complete at this point from the previous programming exercises)


Download ppt "Object Comparisons and Arrays"

Similar presentations


Ads by Google