Course 2 Lesson 1. Strings 1.1 Strings are Immutable Objects Handling "strings" of characters is afundamental aspect of most programming languages. In Java, each character in astring is a 16-bit Unicode character. In Java, strings are objects. Just like other objects, you can create an instance of a String class with the new keyword, as follows: This line of code creates a new object of class String, and assigns it to the reference variable s. Assign a value to the created String object: Once a String object is created it cannot be changed - String objects are immutable. While the String object is immutable, its reference variable is not, so to continue the previous example: Now s references a new String objects whose value is „abcdef more stuff” and the old String „abcdef” still exists in memory but there is no reference to, so there is no way to access it anymore in our code. The following images demonstrateStrings immutability: 1.2 Important methods of String class public char charAt(int index) This method returns the character located at the String's specified index. String indexes are zero-based—for example: public String concat(String s) This method returns a String with the value of the String passed in to the method appended to the end of the String used to invoke the method—for example: public boolean equalsIgnoreCase(String s) This method returns a boolean value (true or false) depending on whether the value of the String in the argument is the same as the value of the String used to invoke the method. This method will return true even when characters in the String objects being comparedhave differing cases—for example: public int length() This method returns the length of the String used to invoke the method—for example: public String replace(char old, char new) This method returns a String whose value is that of the String used to invoke the method, updated so that any occurrence of the char in the first argument is replaced by the char in the second argument: public String substring(int begin) public String substring(int begin, int end) The substring() method is used to return a part (or substring) of the String used to invoke the method. The first argument represents the starting location (zero-based) of the substring. If the call has only one argument, the substring returned will include the characters to the end of the original String. If the call has two arguments, the substring returned will end with the character located in the nth position of the original String where n is thesecond argument. public String toLowerCase() This method returns a String whose value is the String used to invoke the method,but with any uppercase characters converted to lowercase public String toString() This method returns the value of the String used to invoke the method. What? Why would you need such a seemingly "do nothing" method? All objects in Java must have a toString() method, which typically returns a String that in some meaningful way describes the object in question. Example: public String trim() This method returns a String whose value is the String used to invoke the method, but with any leading or trailing blank spaces removed Lesson 2. Primitives vs. Their Wrapper Class 2.1 Primitives An application is made up of variables that store data and code that manipulatesthe data. Java uses primitives to store its most basic data types. These primitives are then used to create more advanced data types called objects. This is what makes Java an object-oriented language. It allows the developer to store related code and data together in discrete objects. Definition:Primitives are a special subset of Java data types. They are the foundation of storing data in a program. The Java language has eight primitives. When a primitive is declared, it reserves a certain number of bits in memory. The size of the memory allocation is dependent on the type of primitive. Each primitive data type has a set size that it will always occupy in memory. 2.1.1 ints An int is the most commonly used Java primitive. Once declared, it has a default value of 0. An int occupies 32 bits in memory and can store a 32-bit signed two’s complement non-floating point number. It has a maximum value of 2,147,483,647 and a minimum value of –2,147,483,648 inclusive. The following code segments demonstrate the uses of int: 2.1.2 floats A float is a primitive that is used to store decimal values. It has a default value of 0.0f. This value is equal to zero, but the “f” or “F” appended to the end indicates that this value is a float, not a double. They require 32 bits in memory and may contain a 32bit value with a maximum of3.4e+38 and a minimum positive nonzero value of 1.4e–45 inclusive. These values are rounded for simplicity. The exact size of a float is a formula that can be found in section 4.2.3 of the official Java Language Specification. 2.1.3 booleans A boolean primitive is used to store a value of true or false. They store a one-bitvalue and will default to false. Although they represent only one bit of information, their exact size is not defined in the Java standard and may occupy more space on different platforms. 2.1.4 chars The char primitive is used to store a single 16-bit Unicode character and requires 16 bits of memory. The range of a char corresponds to the minimum and maximum as defined by the Unicode specification '\u0000' (or 0) and '\uffff' (or 65,535 inclusive), respectively. When a char is set with a character in code, single quotes should be used—'Y', for example. A char has a default value of '\u0000' or 0. This is the only Java primitive that is unsigned. The byte primitive is like an int, but smaller. It stores eight-bit signed integers ranging from –128 to 127 inclusive. A short is also like an int. It is bigger than a byte but smaller than an int. It stores a 16-bit integer ranging from –32768 to 32767 inclusive. The long primitive is also like an int, but twice the size. It stores a 64-bit integer ranging from −263 to263 − 1inclusive. The last primitive is the double. It is like a float and stores up to a 64-bit floating point number. It holds a value in the range of 5𝑒 −324 to a minimum positive non-zero value of 1.8𝑒 +308 , inclusive. Like the float, this range is rounded and the exact formula can be found in the Java Language Specification. 2.2 Wrappers Primitives are the basic building blocks in Java and are one of the few things that are not objects.Java has a built-in wrapper class for each primitive that can convert a primitive to an object. The wrapper classes are Boolean, Byte, Character, Double, Float, Integer, Long, Short. Note that each of these classes starts with a capital letter, whereas the primitive begins with a lowercase letter. If you see a data type Float, it is referring to the object, while the data type float refers to the primitive. As of J2SE 5.0, a primitive will automatically be converted in either direction between its wrapper class and associated primitive. This feature is called autoboxing and unboxing. Primitives and their equivalent objects can, in most cases, be used interchangeably. When performing math operations, using primitives will result in much faster calculations. Primitives also consume a smaller memory footprint. Lesson 3. Generics 3.1 Generics with Collections Arrays in Java have always been type safe—an array declared as type String (String[]) can't accept Integers (or ints), Dogs, or anything other than Strings. But before Java 5 there was no syntax for declaring a type safe collection. To make an ArrayList of Strings, you said: or the polymorphically equivalent There was no syntax that let you specify that myList will take Strings and only Strings. And with no way to specify a type for the ArrayList, the compiler couldn't enforce that you put only things of the specified type into the list. As of Java 5, we can use generics, and while they aren't only for making type safe collections, that's just about all most developers use generics for. 3.2 Advatanges 1. Type-safety: we can hold only a single type of objects in generics. It doesn’t allow to store other objects. 2. Type casting is not required : there is no need to typecast the object Before generics After generics 3. Compile-Time Checking: It is checked at compile time so problem will not occur at runtime. The good programming strategy says it is far better to handle the problem at compile time than runtime 3.3 Generic class Definition: A class that can refer to any type is known as generic class. The T type indicates that it can refer to any type (like String, Integer, Employee …). The type you specify for the class, will be used to store and retrieve the data 3.4 Polymorphism and Generics Generic collections give you the same benefits of type safety that you've had with arrays, but there are some crucial differences. As we’ve seen polymorphism allows us to use „base” type of the collection when creating it In other words, we were able to assign an ArrayList to a List reference, becauseList is a supertype of ArrayList. But what about this? No, it doesn't work. There's a very simple rule here, the type of the variable declaration must match the type you pass to the actual object type. If you declare List<Foo> foo then whatever you assign to the foo reference MUST be of the generic type <Foo>. Not a subtype of<Foo>. Not a supertype of <Foo>. Just <Foo>. These are wrong These are legal With arrays it is different, because we are allowed to do this Lesson 4. Collections A collection, also called container, is an object that groups multiple elements into a single unit. It is used to store, retrieve, manipulate and communicate aggregate data. Java collections hierarchy: The Collection interface is the foundation upon which the collections framework is built. It declares the core methods that all collections will have. Interface Set extends Collection to handle sets, which must contain unique elements. Implementation TreeSet. Interface Listextends Collection and an instance of List stores an ordered collection of elements. Implementation ArrayList. Interface Queue defines methods for insertion, extraction and inspection, typically in a FIFO (first in first out) order; most common implementation is LinkedList. The Map interface maps unique keys to values. A key is an object that you use to retrieve a value. Given a key and a value, you can store the value in a Map object. After the value is stored, you can retrieve it by using its key. Examples 1. List The List interface extends Collection and declares the behavior of a collection that stores a sequence of elements. Elements can be inserted or accessed by their position in the list, using a zerobased index A list may contain duplicate elements Methods: void add(int index, Object obj) Inserts obj into the invoking list at the index passed in index. Any pre-existing elements at or beyond the point of insertion are shifted up. Thus, no elements are overwritten. boolean addAll(int index, Collection c) Inserts all elements of c into the invoking list at the index passed in index. Any preexisting elements at or beyond the point of insertion are shifted up. Thus, no elements are overwritten. Returns true if the invoking list changes and returns false otherwise. Object get(int index) Returns the object stored at the specified index within the invoking collection. int indexOf(Object obj) Returns the index of the first instance of obj in the invoking list. If obj is not an element of the list, .1 is returned. Object remove(int index) Removes the element at position index from the invoking list and returns the deleted element. The resulting list is compacted. That is, the indexes of subsequent elements are decremented by one. Object set(int index, Object obj) Assigns obj to the location specified by index within the invoking list. The java.util.ArrayList class is one of the most commonly used of all the classes in the Collections Framework. It's like an array on vitamins. Some of the advantages ArrayList has over arrays are It can grow dynamically It provides more powerful insertion and search mechanisms than arrays Output: ? Iterator An Iterator is an object that's associated with a specific collection. It lets you loop through the collection step by step. The most important two methods of it are: boolean hasNext()returns true if there is at least one more element inthe collection being traversed. Invoking hasNext() does NOT move you tothe next element of the collection Object next()this method returns the next object in the collection, AND moves you forward to the element after the element just returned Output: ? 2. Set A Set is a Collection that cannot contain duplicate elements. It models the mathematical set abstraction. The Set interface contains only methods inherited from Collection and adds the restriction that duplicate elements are prohibited. Set have its implementation HashSet,TreeSet,LinkedHashSet. Example: in various classes like Output: ? 3.Map The Map interface maps unique keys to values. A key is an object that you use to retrieve a value. Given a key and a value, you can store the value in a Map object. After the value is stored, you can retrieve it by using its key. Methods: boolean containsKey(Object k) Returns true if the invoking map contains k as a key. Otherwise, returns false. boolean containsValue(Object v) Returns true if the map contains v as a value. Otherwise, returns false. Object get(Object k) Returns the value associated with the key k. Object put(Object k, Object v) Puts an entry in the invoking map, overwriting any previous value associated with the key. The key and value are k and v, respectively. Returns null if the key did not already exist. Otherwise, the previous value linked to the key is returned. Key methods in List, Set and Map Lesson 5. Comparing objects Both equals() and == operator in Java is used to compare objects to check equality but main difference between equals method and == operator is that former is method and later is operator. Operator ==behaves identical for every object but equals() is method, which can be overridden in Java and logic to compare objects can be changed based upon business rules. Another notable difference between == and equals method is that former is used to compare both primitive and objects while later is only used for objects comparison. 1. What is „==” in Java? Operator "==" or equality operator in Java is a binary operator provided by Java programming language and used to compare primitives and objects. In terms of comparing primitives like boolean, int, float "==" works fine but when it comes to compare objects it creates confusion with equals method in Java. "==" compare two objects based on memory reference. so "==" operator will return true only if two object reference it is comparing represent exactly same object otherwise "==" will return false. 2. What is equals() in Java? Equals() method is defined in Object class in Java and used for checking equality of two object defined by business logic e.g. two Employees are considered equal if they have same empId etc. You can have your object defined and than override equals method for defining condition on which two domain objects will be considered equal. Example: Output: ? When overriding equals ()you should respect the followings rules: It is reflexive: for any non-null reference value x, x.equals(x) should return true It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified For any non-null reference value x, x.equals(null) should return false 3. What is Comparable interface in Java? The Comparable interface is used by the Collections.sort() method andthe java.util.Arrays.sort() method to sort Lists and arrays of objects,respectively. To implement Comparable, a class must implement a single method,compareTo(). Here's an invocation of compareTo(): The compareTo() method returns an int with the following characteristics: negative If thisObject < anotherObject zero If thisObject == anotherObject positive If thisObject > anotherObject Example: