Notes
- class can make an object
- an interface allows you to define the methods that you want in the class, you cannot instantiate them
- each class is automatically an object
- making a copy of an array adds to the space complexity
- 2 nested loops , complexity of the algorithmn is double because it requires you to loop twice
- you can convert from an object reference type to an array reference type to change the behavior of the code
- java has built in toString() on basically everything
- Abstract class: is a restricted class that cannot be used to create objects, it can have abstract and nonabstract methods, it can have constructors and static methods, it can have final methods
- Abstract method: can only be used in an abstract class, and it does not have a body.
- making one thing that works for all the instantiated object is what static does
- link list allows you to add and remove the objects?
- linked list has data and collections
- each node has a data that must be connected to other nodes
- they each have data and they need to point to each other
- ex: each individual cupcakes would be the nodes
- nodes would be added and removed. you would have to manage all the references to the cupcake to make it work
- the data strcture must be trained to iterate
- group of individual objects represented by a single unit is called a collection
- There is a collection framework and map
- framework - a set olf classes and interfaces that are ready made
- interfaces are made up of methods that do not have a body
- classes implement those methods and build the bodies within the class interfaces cannnot be used to create objects
- in implementing an interface, you have to override all of its methods
- interface methods are by default abstract and public
- interface attributes are by default public, static, and final
Queue<String> queue = new LinkedList<>(); // Queue interface uses LL implementation
queue.add("John");
queue.add("Jane");
queue.add("Bob");
// Collections has a toArray convertion
Object[] arr = queue.toArray();
// Empty queue
System.out.println("Empty Queue");
while (queue.size() > 0) // Interate while size
System.out.println(queue.remove());
// Iterate of array
System.out.println("Iterate over Array");
for (Object a : arr) // Type is Object from convertion
System.out.println(a);
Notes from CollegeBoard
- constructing objects using classes
- not having a void requires you to specific the return type from the function
- accessor methods get(); they return a value
- mutator/modifier methods; they change the state of the object
- calling methods on objects
- declare the name of the class, then the name of the object, then the equals, then new "class"
- object.method() is the format
- calling static methods in classes
- static methodsdo not use object.method() convention it uses class.method()
- you dont have to cresate these methods
- ex: Math class, Math.abs(-45);
- these are static methods
- using the string class
- String is a class to create objects with
- object.method() format since these are not static metods
LinkedList
- similar to an arraylist
- you can add, change, remove items, and clear the list
- they differ because arraylist stores elements in the array and once the array is not big enough, it creates a new array to replace the old one
- LinkedList store items in containers
- the list has a link to each container and each container has a link to the next item in the lsit
- to add an elementto the list, a new container is created and that container is linked to the other containers
- LinkedList is better for manipulating data
- elements are lined using pointers and adresses
- each element is known as a node and a separate object
- ListedList is a dynamic array that does not need to specific the size while creating it
- LinkList a = new ListedList() -- empty LinkedList
- LinkedList a = new LinkedList(Collection C) -- creates an ordered list that contains elements from a specific collection
Queue
- linear ordered data structure
- element inserted first in the queue will be te first element to be removed
- queue is an interface tat inherits the collection interface
- queue has two ends, the front and rear
- elements are added at the rear and removed from the front
- bottom to top kinda like throwing up
- queue is an interface so it cannot be instanitated
- classes need to implement the functionality of the queue
- linkedlist implements the queue interface
- the queuve provides methods like insertion and deletion
- Queue
a = new LinkedList<> ();</li> </ul> Stack
- stack is faster than queue
- stack data structure
- last in first out
- push and pop operations
- empty, search, peek operations
- Stack
stack = new Stack ();</li> </ul> </div> </div> </div> Generic T and Iterable Interface
- Iterators are used to retrieve elements one by one
- Iterator interface is used when designing custom data structures
- need to implement iterable interface and its methods
- cursor or pointer keeps track of what element that we are currently on
- to progress from one element to another the next() method is used which returns the current element and advances the cursor to the next
- hasNext() check if there is another element for the pointer to advance to, false if the end of the collection is reached
- remove() removes the last element retgutrned by the iterator from the collection
- forEachRemaining() performs given action for each remaining element in a collection, in sequential order
- in a linkedlist the cursor is initialized to the head elemet or the entry point into the list or the first node
- iterable interface allows an object to be the target of enhaved for loop
- T is the type of element returned by the Iterator
- universla iterator can be applied to any collection object
- generics allow for reusable components of code rather than creating a variety of the same thing, parameterize a class, method, or interface
- T stands for Type, unspecifed Type of data or parameter
- T can only be used for objects and wrappers not primitives
- When using Generics the T goes away in place of anything that can extend the object class
- which primitives cannot do
- Generics are beneficial because they have better compile- time checking, reusability, and great for data structures and algorithmns
/* This is wrapper class... Objective would be to push more functionality into this Class to enforce consistent definition */ public abstract class Generics { public final String masterType = "Generic"; private String type; // extender should define their data type // generic enumerated interface public interface KeyTypes { String name(); } protected abstract KeyTypes getKey(); // this method helps force usage of KeyTypes // getter public String getMasterType() { return masterType; } // getter public String getType() { return type; } // setter public void setType(String type) { this.type = type; } // this method is used to establish key order public abstract String toString(); // static print method used by extended classes public static void print(Generics[] objs) { // print 'Object' properties System.out.println(objs.getClass() + " " + objs.length); // print 'Generics' properties if (objs.length > 0) { Generics obj = objs[0]; // Look at properties of 1st element System.out.println( obj.getMasterType() + ": " + obj.getType() + " listed by " + obj.getKey()); } // print "Generics: Objects' for(Object o : objs) // observe that type is Opaque System.out.println(o); System.out.println(); } }
public class Level extends Generics { public static KeyTypes key = KeyType.title; public static void setOrder(KeyTypes key) { Level.key = key; } public enum KeyType implements KeyTypes {title, number, name, topic, difficulty, time, hint, hintContent} private final int number; private final String name; private final String topic; private final String difficulty; private final int time; private final boolean hint; private final String hintContent; public Level(int number, String name, String topic, String difficulty, int time, boolean hint, String hintContent) { super.setType("Level"); this.number = number; this.name = name; this.topic = topic; this.difficulty = difficulty; this.time = time; this.hint = hint; this.hintContent = hintContent; } @Override protected KeyTypes getKey() { return Level.key; } @Override public String toString() { String output=""; if (KeyType.number.equals(this.getKey())) { output += "00" + this.number; output = output.substring(output.length() - 2); } else if (KeyType.name.equals(this.getKey())) { output += this.name; } else if (KeyType.topic.equals(this.getKey())) { output += this.topic; } else if (KeyType.difficulty.equals(this.getKey())) { output += this.difficulty; } else if (KeyType.time.equals(this.getKey())) { output += "00" + this.time; output = output.substring(output.length() - 2); } else if (KeyType.hint.equals(this.getKey())) { output += this.hint; } else if (KeyType.hintContent.equals(this.getKey())) { output += this.hintContent; } else { output += super.getType() + ": " + this.number + ", " + this.topic + ", " + this.difficulty + ", " + this.time + ", " + this.hint + ", " + this.hintContent; } return output; } public static Level[] levels() { return new Level[]{ new Level(1, "The Village","If Statements", "Easy", 30, true, "Try debugging"), new Level(2,"The Jungle", "For Loops", "Medium", 60, false, "Take your time"), new Level(3, "The Forest","De Morgan's Law", "Hard", 90, true, "Make a table for true and false"), }; } public static void main(String[] args){ Level[] objs = levels(); Level.setOrder(KeyType.title); Level.print(objs); Level.setOrder(KeyType.name); Level.print(objs); Level.setOrder(KeyType.difficulty); Level.print(objs); } } Level.main(null);
public class Cupcake extends Generics { // Class data public static KeyTypes key = KeyType.title; // static initializer public static void setOrder(KeyTypes key) {Cupcake.key = key;} public enum KeyType implements KeyTypes {title, flavor, frosting, sprinkles} // Instance data private final String frosting; private final int sprinkles; private final String flavor; // Constructor Cupcake(String frosting, int sprinkles, String flavor) { this.setType("Cupcake"); this.frosting = frosting; this.sprinkles = sprinkles; this.flavor = flavor; } /* 'Generics' requires getKey to help enforce KeyTypes usage */ @Override protected KeyTypes getKey() { return Cupcake.key; } /* 'Generics' requires toString override * toString provides data based off of Static Key setting */ @Override public String toString() { String output=""; if (KeyType.flavor.equals(this.getKey())) { output += this.flavor; } else if (KeyType.frosting.equals(this.getKey())) { output += this.frosting; } else if (KeyType.sprinkles.equals(this.getKey())) { output += "00" + this.sprinkles; output = output.substring(output.length() - 2); } else { output = super.getType() + ": " + this.flavor + ", " + this.frosting + ", " + this.sprinkles; } return output; } // Test data initializer public static Cupcake[] cupcakes() { return new Cupcake[]{ new Cupcake("Red", 4, "Red Velvet"), new Cupcake("Orange", 5, "Orange"), new Cupcake("Yellow", 6, "Lemon"), new Cupcake("Green", 7, "Apple"), new Cupcake("Blue", 8, "Blueberry"), new Cupcake("Purple", 9, "Blackberry"), new Cupcake("Pink", 10, "Strawberry"), new Cupcake("Tan", 11, "Vanilla"), new Cupcake("Brown", 12, "Chocolate"), }; } public static void main(String[] args) { // Inheritance Hierarchy Cupcake[] objs = cupcakes(); // print with title Cupcake.setOrder(KeyType.title); Cupcake.print(objs); // print flavor only Cupcake.setOrder(KeyType.flavor); Cupcake.print(objs); } } Cupcake.main(null);
/* * Animal class extends Generics and defines abstract methods */ public class Animal extends Generics { // Class data public static KeyTypes key = KeyType.title; // static initializer public static void setOrder(KeyTypes key) { Animal.key = key; } public enum KeyType implements KeyTypes {title, name, age, color} // Instance data private final String name; private final int age; private final String color; /* constructor * */ public Animal(String name, int age, String color) { super.setType("Animal"); this.name = name; this.age = age; this.color = color; } /* 'Generics' requires getKey to help enforce KeyTypes usage */ @Override protected KeyTypes getKey() { return Animal.key; } /* 'Generics' requires toString override * toString provides data based off of Static Key setting */ @Override public String toString() { String output=""; if (KeyType.name.equals(this.getKey())) { output += this.name; } else if (KeyType.age.equals(this.getKey())) { output += "00" + this.age; output = output.substring(output.length() - 2); } else if (KeyType.color.equals(this.getKey())) { output += this.color; } else { output += super.getType() + ": " + this.name + ", " + this.color + ", " + this.age; } return output; } // Test data initializer public static Animal[] animals() { return new Animal[]{ new Animal("Lion", 8, "Gold"), new Animal("Pig", 3, "Pink"), new Animal("Robin", 7, "Red"), new Animal("Cat", 10, "Black"), new Animal("Kitty", 1, "Calico"), new Animal("Dog", 14, "Brown") }; } /* main to test Animal class * */ public static void main(String[] args) { // Inheritance Hierarchy Animal[] objs = animals(); // print with title Animal.setOrder(KeyType.title); Animal.print(objs); // print name only Animal.setOrder(KeyType.name); Animal.print(objs); } } Animal.main(null);
public class Alphabet extends Generics { // Class data public static KeyTypes key = KeyType.title; // static initializer public static void setOrder(KeyTypes key) {Alphabet.key = key;} public enum KeyType implements KeyTypes {title, letter} private static final int size = 26; // constant used in data initialization // Instance data private final char letter; /* * single letter object */ public Alphabet(char letter) { this.setType("Alphabet"); this.letter = letter; } /* 'Generics' requires getKey to help enforce KeyTypes usage */ @Override protected KeyTypes getKey() { return Alphabet.key; } /* 'Generics' requires toString override * toString provides data based off of Static Key setting */ @Override public String toString() { String output=""; if (KeyType.letter.equals(this.getKey())) { output += this.letter; } else { output += super.getType() + ": " + this.letter; } return output; } // Test data initializer for upper case Alphabet public static Alphabet[] alphabetData() { Alphabet[] alphabet = new Alphabet[Alphabet.size]; for (int i = 0; i < Alphabet.size; i++) { alphabet[i] = new Alphabet( (char)('A' + i) ); } return alphabet; } /* * main to test Animal class */ public static void main(String[] args) { // Inheritance Hierarchy Alphabet[] objs = alphabetData(); // print with title Alphabet.setOrder(KeyType.title); Alphabet.print(objs); // print letter only Alphabet.setOrder(KeyType.letter); Alphabet.print(objs); } } Alphabet.main(null);
/** * Implementation of a Double Linked List; forward and backward links point to adjacent Nodes. * */ public class LinkedList<T> { private T data; private LinkedList<T> prevNode, nextNode; /** * Constructs a new element * * @param data, data of object * @param node, previous node */ public LinkedList(T data, LinkedList<T> node) { this.setData(data); this.setPrevNode(node); this.setNextNode(null); } /** * Clone an object, * * @param node object to clone */ public LinkedList(LinkedList<T> node) { this.setData(node.data); this.setPrevNode(node.prevNode); this.setNextNode(node.nextNode); } /** * Setter for T data in DoubleLinkedNode object * * @param data, update data of object */ public void setData(T data) { this.data = data; } /** * Returns T data for this element * * @return data associated with object */ public T getData() { return this.data; } /** * Setter for prevNode in DoubleLinkedNode object * * @param node, prevNode to current Object */ public void setPrevNode(LinkedList<T> node) { this.prevNode = node; } /** * Setter for nextNode in DoubleLinkedNode object * * @param node, nextNode to current Object */ public void setNextNode(LinkedList<T> node) { this.nextNode = node; } /** * Returns reference to previous object in list * * @return the previous object in the list */ public LinkedList<T> getPrevious() { return this.prevNode; } /** * Returns reference to next object in list * * @return the next object in the list */ public LinkedList<T> getNext() { return this.nextNode; } }
import java.util.Iterator; /** * Queue Iterator * * 1. "has a" current reference in Queue * 2. supports iterable required methods for next that returns a generic T Object */ class QueueIterator<T> implements Iterator<T> { LinkedList<T> current; // current element in iteration // QueueIterator is pointed to the head of the list for iteration public QueueIterator(LinkedList<T> head) { current = head; } // hasNext informs if next element exists public boolean hasNext() { return current != null; } // next returns data object and advances to next position in queue public T next() { T data = current.getData(); current = current.getNext(); return data; } } /** * Queue: custom implementation * @author John Mortensen * * 1. Uses custom LinkedList of Generic type T * 2. Implements Iterable * 3. "has a" LinkedList for head and tail */ public class Queue<T> implements Iterable<T> { LinkedList<T> head = null, tail = null; /** * Add a new object at the end of the Queue, * * @param data, is the data to be inserted in the Queue. */ public void add(T data) { // add new object to end of Queue LinkedList<T> tail = new LinkedList<>(data, null); if (this.head == null) // initial condition this.head = this.tail = tail; else { // nodes in queue this.tail.setNextNode(tail); // current tail points to new tail this.tail = tail; // update tail } } /** * Returns the data of head. * * @return data, the dequeued data */ public T delete() { T data = this.peek(); if (this.tail != null) { // initial condition this.head = this.head.getNext(); // current tail points to new tail if (this.head != null) { this.head.setPrevNode(tail); } } return data; } /** * Returns the data of head. * * @return this.head.getData(), the head data in Queue. */ public T peek() { return this.head.getData(); } /** * Returns the head object. * * @return this.head, the head object in Queue. */ public LinkedList<T> getHead() { return this.head; } /** * Returns the tail object. * * @return this.tail, the last object in Queue */ public LinkedList<T> getTail() { return this.tail; } /** * Returns the iterator object. * * @return this, instance of object */ public Iterator<T> iterator() { return new QueueIterator<>(this.head); } }
import java.util.*; /** * Queue Manager * 1. "has a" Queue * 2. support management of Queue tasks (aka: titling, adding a list, printing) */ class QueueManager<T> { // queue data private final String name; // name of queue private int count = 0; // number of objects in queue public final Queue<T> queue = new Queue<>(); // queue object /** * Queue constructor * Title with empty queue */ public QueueManager(String name) { this.name = name; } /** * Queue constructor * Title with series of Arrays of Objects */ public QueueManager(String name, T[]... seriesOfObjects) { this.name = name; this.addList(seriesOfObjects); this.deleteList(seriesOfObjects); } /** * Add a list of objects to queue */ public void addList(T[]... seriesOfObjects) { //accepts multiple generic T lists for (T[] objects: seriesOfObjects) for (T data : objects) { this.count++; System.out.println("Enquenced data: " + data); this.queue.add(data); System.out.print(this.name + " count: " + count + ", data: "); for (T x:queue) System.out.print(x + " "); System.out.println(); System.out.println(); } } public void deleteList(T[]... seriesOfObjects) { for (T[] objects: seriesOfObjects) for (T data : objects) { this.count--; System.out.println("Dequeued data: " + data); this.queue.delete(); System.out.print(this.name + " count: " + count + ", data: "); for (T x:queue) System.out.print(x + " "); System.out.println(); System.out.println(); } } /** * Print any array objects from queue */ public void printQueue() { System.out.println(this.name + " count: " + count); System.out.print(this.name + " data: "); for (T data : queue) System.out.print(data + " "); System.out.println(); } }
import java.util.*; /** * Driver Class * Tests queue with string, integers, and mixes of Classes and types */ class QueueTester { public static void main(String[] args) { // Create iterable Queue of Words Object[] words = new String[] { "seven", "slimy", "snakes", "sallying", "slowly", "slithered", "southward"}; QueueManager qWords = new QueueManager("Words", words ); qWords.printQueue(); } } QueueTester.main(null);
/** * Driver Class * Tests queue with string, integers, and mixes of Classes and types */ class QueueTester { public static void main(String[] args) { // Create iterable Queue of Words Object[] words = new String[] { "seven", "slimy", "snakes", "sallying", "slowly", "slithered", "southward"}; QueueManager qWords = new QueueManager("Words", words ); qWords.printQueue(); // Create iterable Queue of Integers Object[] numbers = new Integer[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; QueueManager qNums = new QueueManager("Integers", numbers ); qNums.printQueue(); // Create iterable Queue of NCS Generics Animal.setOrder(Animal.KeyType.name); Alphabet.setOrder(Alphabet.KeyType.letter); Cupcake.setOrder(Cupcake.KeyType.flavor); Level.setOrder(Level.KeyType.name); // Illustrates use of a series of repeating arguments QueueManager qGenerics = new QueueManager("My Generics", Alphabet.alphabetData(), Animal.animals(), Cupcake.cupcakes(), Level.levels() ); qGenerics.printQueue(); // Create iterable Queue of Mixed types of data QueueManager qMix = new QueueManager("Mixed"); qMix.queue.add("Start"); qMix.addList( words, numbers, Alphabet.alphabetData(), Animal.animals(), Cupcake.cupcakes(), Level.levels() ); qMix.queue.add("End"); qMix.printQueue(); } } QueueTester.main(null);