Collection interface

What is Collection Interface

The Collection interface in Java is the foundation of the Java Collections Framework. It represents a group of objects, known as elements, and provides a set of methods to manipulate and operate on these elements.

The Collection interface is a root interface that extends the Iterable interface, allowing collections to be iterated over using the enhanced for loop or Iterator interface. Since, it is root interface, polymorphically it provides maximum generality.

The AbstractCollection class in Java is an abstract base class that provides a skeletal implementation of the Collection interface. It serves as a convenient starting point for creating custom collection classes by handling common functionality and reducing the implementation effort required for concrete collection classes.

Collection interface extends another interface called Iterable interface which would enable any collection object to be used in for each loops.


Collection interface syntax as in Java API

public interface Collection<E> extends Iterable<E> {
    // Basic Operations
    boolean add(E e);
    boolean remove(Object o);
    boolean contains(Object o);
    int size();
    boolean isEmpty();
    void clear();

    // Bulk Operations
    boolean addAll(Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> c);
    boolean containsAll(Collection<?> c);
    void clear(); // optional, removes all elements from collection.
  
    // Array Conversion
    Object[] toArray();
    <T> T[] toArray(T[] a);

    // Iteration
    Iterator<E> iterator();

    // Stream Support (Java 8+)
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

In the above syntax, the Collection interface is defined as a generic interface (Collection<E>) that can work with elements of any specific type represented by the type parameter E.

The interface extends the Iterable interface, allowing collections to be iterated over using the enhanced for loop or the Iterator interface.


Collection interface methods

The Collection interface defines a set of methods categorized as basic operations, bulk operations, array conversion, iteration, and stream support (added in Java 8).

The basic operations include methods like add(), remove(), contains(), size(), isEmpty(), and clear(). These methods provide common functionality for adding, removing, checking the presence of elements, and managing the size and emptiness of the collection.

The bulk operations include methods like addAll(), removeAll(), retainAll(), and containsAll(). These methods allow collections to be modified based on other collections, such as adding all elements from another collection, removing elements common to another collection, retaining only elements from another collection, and checking if the collection contains all elements of another collection.

The array conversion methods toArray() and toArray(T[] a) allow the collection to be converted into an array. The first method returns an Object array, while the second method allows specifying the type of the array.

The iterator() method returns an Iterator over the elements of the collection, allowing for iteration and sequential access to the elements.

Starting from Java 8, the stream() and parallelStream() methods are provided for supporting streaming operations using the Stream API.

Concrete implementations of the Collection interface, such as ArrayList, LinkedList, and HashSet, provide additional methods and functionalities specific to their implementations.


Examples

<T> T[] toArray(T[] a) method

import java.util.ArrayList;
import java.util.List;

public class ToArrayExample {
    public static void main(String[] args) {
        List<String> myList = new ArrayList<>();
        myList.add("Hello");
        myList.add("World");

        // Create an array of String with the same size as the list
        String[] array = new String[myList.size()];

        // Convert the list to an array using the toArray() method
        String[] resultArray = myList.toArray(array);

        // Print the elements of the resulting array
        for (String element : resultArray) {
            System.out.println(element);
        }
    }
}

In this example, we have a List of strings called myList. We want to convert this list to an array of strings using the toArray(T[] a) method.

First, we create a String array called array with the same size as the list using myList.size(). Then, we call the toArray() method on the myList object and pass array as the argument.

** The toArray(T[] a) method takes the provided array as an argument and populates it with the elements of the list. If the provided array is large enough to accommodate all the elements, it will be used. Otherwise, a new array of the same runtime type and size will be created and returned.

This usage of toArray(T[] a) allows you to convert a List or any other Collection into an array of the desired type. It provides a way to obtain an array representation of the collection’s elements, which can be useful in scenarios where you specifically need an array or want to interface with code that requires an array.

Object[] toArray()

import java.util.ArrayList;
import java.util.List;

public class ToArrayExample {
    public static void main(String[] args) {
        List<String> myList = new ArrayList<>();
        myList.add("Hello");
        myList.add("World");

        // Convert the list to an array using the toArray() method
        Object[] resultArray = myList.toArray();

        // Print the elements of the resulting array
        for (Object element : resultArray) {
            System.out.println(element);
        }
    }
}

In this example, we have a List of strings called myList. We want to convert this list to an array of Object using the toArray() method.

We simply call the toArray() method on the myList object without passing any argument. The toArray() method returns an array of Object, where each element of the list is copied into the corresponding position of the array.

Finally, we iterate over the resulting array (resultArray) and print its elements. Since the resultArray is of type Object[], we need to use the Object type to iterate over the elements.

The toArray() method is useful when you need to obtain a generic array representation of a List or any other Collection. However, keep in mind that the resulting array will have the runtime type of Object[].

** If you require a specific type of array, you can use the overloaded toArray(T[] a) method and pass an array of the desired type.


How to enable your class objects to be iterable

To enable your class objects to be iterable, you need to implement the Iterable interface and provide an implementation of the iterator() method. This allows instances of your class to be used in enhanced for loops or with the Iterator interface for iteration.

Here’s an example of how to enable your class objects to be iterable:

import java.util.Iterator;

public class MyIterableClass<T> implements Iterable<T> {
    private T[] elements;

    public MyIterableClass(T[] elements) {
        this.elements = elements;
    }

    // provide an implementation for iterator() method
    @Override
    public Iterator<T> iterator() {
        return new MyIterator();
    }

    // private class implementing Iterator interface
    private class MyIterator implements Iterator<T> {
        private int currentIndex = 0;

        @Override
        public boolean hasNext() {
            return currentIndex < elements.length;
        }

        @Override
        public T next() {
            return elements[currentIndex++];
        }
    }

    // Other methods and code specific to your class
}

In the example above, the MyIterableClass implements the Iterable interface by specifying the type parameter <T>. It provides an implementation of the iterator() method that returns an instance of the custom MyIterator class.

The MyIterator class implements the Iterator interface and defines the hasNext() and next() methods required for iteration. It keeps track of the current index to provide the next element from the array of elements.

With this implementation, you can use instances of MyIterableClass in enhanced for loops or with the Iterator interface as follows:

MyIterableClass<String> iterable = new MyIterableClass<>(new String[]{"Hello", "World"});

// Using enhanced for loop
for (String element : iterable) {
    System.out.println(element);
}

// Using Iterator
Iterator<String> iterator = iterable.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    System.out.println(element);
}

By implementing the Iterable interface and providing an iterator implementation, you enable your class objects to be

  • iterated over using enhanced for loops or
  • by obtaining an iterator explicitly.

This allows for a more intuitive and convenient way of working with instances of your class in iterative scenarios.


Collections Framework – Introduction

What is Collections Framework

The Collections Framework in Java is a unified architecture that provides a set of interfaces, classes, and algorithms to manipulate and store collections of objects. It was introduced in Java 1.2 and is part of the java.util package.

The Collections Framework offers a wide range of data structures, such as lists, sets, queues, and maps, along with various utility classes for working with collections. These structures and utilities are designed to be efficient, flexible, and reusable.

These are ready to use, highly efficient data structures which we can use right out of the box without having to implement ourselves.

Key components of the Collections Framework

Here are some key components of the Collections Framework:

  1. Interfaces: The framework defines several core interfaces, including List, Set, Queue, Map, and their sub-interfaces. These interfaces provide common methods and contracts for working with collections.
  2. Implementations: The framework provides various classes that implement the collection interfaces. For example, ArrayList and LinkedList are implementations of the List interface, HashSet and TreeSet implement the Set interface, and HashMap and TreeMap implement the Map interface. These implementations offer different performance characteristics and behaviors to suit different needs.
  3. Algorithms: The Collections class provides a set of algorithms, such as sorting, searching, shuffling, and reversing, which can be applied to collections. These algorithms are implemented as static methods and can be used with any collection that satisfies the requirements.
  4. Utility classes: The Collections Framework includes utility classes like Collections and Arrays that provide additional functionality for manipulating and working with collections. These classes offer methods for operations like collection conversion, synchronization, and filling collections with default values.

The Collections Framework simplifies the process of working with collections by providing a consistent and standardized way to handle them. It promotes code reusability and improves code quality by encouraging the use of interfaces and providing efficient implementations for common collection types.

General Requirements

General requirements which need to be fulfilled by data structures for real world use cases :

  1. No knowledge about size
  2. Automatically extendable
  3. Fast random access
  4. Fast lookups
  5. Ordered vs Unordered
  6. null vs non-null data
  7. Duplicate vs Unique
  8. Automatic sorting
  9. <key, value> mapping

Collections Framework includes different kinds of data structures that would meet one or more of these requirements.

Core Interfaces in Collections Framework

source – https://techvidvan.com/tutorials/java-collection-framework/

  • Collection – would represent a collection of objects.
  • Map – would represent <key, value> pairs.

Most of the implementation permit storing null values; the implementations are not synchronized.

SortedSet, SortedMap – as the name implies they ensure that the data they store is automatically sorted, meaning elements are placed at appropriate positions.

NOTE – Set implementations internally use Map implementations.


Legacy Implementations

In the Java Collections Framework, there are certain legacy implementations that have been retained for compatibility reasons but are generally considered less preferred than their modern alternatives.

The legacy implementations are considered less efficient due to factors such as synchronization overhead, lack of type safety, and limited functionality. The modern alternatives provide improved performance, type safety, and additional features.

Legacy implementations – these are synchronized data structures. Recommended, not to use these classes any more.

  • Vector – replace with ArrayList, LinkedList
  • HashTable – replace with HashMap, LinkedHashMap
  • Stack – replace with ArrayDeque


Set implementation uses Map

In Java, the implementation of the Set interface in the Collections Framework often internally uses a Map implementation to store its elements.

The Set interface is designed to store a collection of unique elements, where duplicates are not allowed. To ensure uniqueness, Set implementations rely on the keys of a Map to store the elements. The elements themselves are stored as keys, leveraging the fact that a Map cannot contain duplicate keys.

When adding elements to a Set, the implementation typically adds the elements as keys into an underlying Map implementation and uses a dummy value (e.g., Boolean.TRUE) as the associated value.

  • The map’s key set represents the elements of the Set, and the uniqueness property is automatically enforced by the map’s behavior.

By utilizing a Map internally, Set implementations can take advantage of the efficient key-based operations provided by the map, such as constant-time contains, add, and remove operations, which are crucial for maintaining the integrity of a Set.

It’s important to note that the specific implementation details may vary across different Set implementations in Java, such as HashSet, TreeSet, or LinkedHashSet. However, the underlying usage of a Map data structure to enforce uniqueness remains a common approach.


Java Collection Framework classes – Serializable

Most of the implementations in Collection Framework are serializable.

In Java, when a class implements the Serializable interface, it means that objects of that class can be converted into a stream of bytes and then saved to a file or transferred over a network. The process of converting an object into a stream of bytes is known as serialization.

The Serializable interface acts as a marker interface, meaning it does not define any methods that need to be implemented. Its purpose is to indicate that an object of the implementing class can be serialized.

For the Java Collections Framework, many of the classes and interfaces, including List, Set, Map, and their implementations like ArrayList, HashSet, HashMap, etc., are designed to be serializable. This allows you to serialize instances of these classes and store them persistently or transmit them across a network.

When a collection class is serializable, it means you can write the collection object to an ObjectOutputStream and read it back from an ObjectInputStream, preserving its state and contents.

Here’s an example of serializing a List implementation (ArrayList) to a file:

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class SerializationExample {
    public static void main(String[] args) {
        List<String> myList = new ArrayList<>();
        myList.add("Hello");
        myList.add("World");

        // Serialize the list to a file
        try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("list.ser"))) {
            outputStream.writeObject(myList);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Deserialize the list from the file
        try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("list.ser"))) {
            List<String> deserializedList = (List<String>) inputStream.readObject();
            System.out.println(deserializedList);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

In this example, the ArrayList object myList is serialized to a file named list.ser. Later, the list is deserialized and printed, restoring its original state.

** It’s worth noting that not all classes in the Java Collections Framework are serializable. For example, concurrent collections like ConcurrentHashMap and specialized collections like PriorityQueue may not implement the Serializable interface due to their complex internal state or synchronization requirements.

When using serialization, it’s important to be aware of the potential issues related to versioning, security, and compatibility between different Java versions or platforms. It’s recommended to carefully design and test the serialization and deserialization process to ensure data integrity and compatibility.


Java Collection Framework classes – Clone

In the Java Collections Framework, some classes provide a clone() method to create a shallow copy of the object. The clone() method creates a new instance of the same class and copies the values of the internal data structures and fields into the new instance. However, it’s important to note that the clone() method is considered to be somewhat problematic and is not widely used in modern Java programming.

  • By default, the clone() method creates a shallow copy of the object. This means that the internal data structures are not cloned deeply, and both the original and cloned objects share references to the same objects. Changes made to the shared objects may affect both the original and cloned instances.
  • Required Casting: The clone() method returns a copy of the object as an Object type. To use the cloned object as the specific type, you need to cast it appropriately. For example:
ArrayList<String> originalList = new ArrayList<>();
originalList.add("Hello");
originalList.add("World");

ArrayList<String> clonedList = (ArrayList<String>) originalList.clone();

Alternatives: In modern Java programming, it is often recommended to use alternative approaches for creating copies of objects, such as copy constructors, factory methods, or the copyOf() methods provided by some collection classes (List.copyOf(), Set.copyOf(), etc.). These approaches provide more control and clarity over the copying process.

To summarize, while the clone() method exists in some classes of the Java Collections Framework, it is generally not recommended to use clone() method due to its limitations and potential issues. It is advisable to consider alternative approaches for creating copies of objects that better suit the requirements of your specific use case.


SQL commands

These SQL commands are run on MySQL :

To connect to MySQL

mysql -u root -p
<-- it will prompt for password -->

To list available databases

SHOW DATABASES;

Create Database

The general command for creating a database:

CREATE DATABASE <database_name>;
CREATE DATABASE soap_store;

Drop database

DROP DATABASE <database-name>;

To use a database

USE <database-name>;

Create table

syntax :

    CREATE TABLE cats (
        name VARCHAR(50),
        age INT
    );
     
    CREATE TABLE dogs (
        name VARCHAR(50),
        breed VARCHAR(50),
        age INT
    );

Display all tables in database / Table Structure

SHOW TABLES;
SHOW COLUMNS FROM <tablename>;    <-- this command to see the table structure
(or)
DESC <tablename>;

Dropping tables / Deleting table

-- To drop a table
DROP TABLE <tablename>;

Create the table:

    CREATE TABLE pastries
      (
        name VARCHAR(50),
        quantity INT
      );
-- table creation
CREATE TABLE IF NOT EXISTS APP_LOGS
(
    LOG_ID              INT AUTO_INCREMENT NOT NULL UNIQUE KEY,
    DB_SESSION_ID       INT                NOT NULL, 
    MODULE              VARCHAR(255)           NULL,
    TYPE                VARCHAR(16)            NULL,
    MESSAGE             TEXT                   NULL,     
    LOG_DATE            TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP
);

View tables:

SHOW TABLES;

View details of pastries table:

DESC pastries;

Delete the whole pastries table:

DROP TABLE pastries;

INSERT: The Basics

-- while inserting data - the order matters : column names and the data values
INSERT INTO cats (name, age) VALUES ('Blue Steele', 5);

-- switching order of age and name
INSERT INTO cats (age, name) VALUES (3, 'Scottish Beth');

INSERT INTO cats (name, age) 
       VALUES ('Jenkins', 7);


-- after inserting data, if you want to know data exists or not
-- To view all rows in our table
SELECT * FROM cats;

Multiple Inserts

-- inserting multiple rows with a single INSERT statement
INSERT INTO cats (name, age) 
       VALUES 
          ('Meatball', 5), 
          ('Turkey', 1), 
          ('Potato Face', 15);

Exercise :

    CREATE TABLE people
      (
        first_name VARCHAR(20),
        last_name VARCHAR(20),
        age INT
      );

    INSERT INTO people(first_name, last_name, age)
    VALUES ('Tina', 'Belcher', 13);

    INSERT INTO people(age, last_name, first_name)
    VALUES (42, 'Belcher', 'Bob');

    --  inserting multiple rows with single INSERT statement
    INSERT INTO people(first_name, last_name, age)
           VALUES
                ('Linda', 'Belcher', 45),
                ('Phillip', 'Frond', 38),
                ('Calvin', 'Fischoeder', 70);

Using NOT NULL

    CREATE TABLE cats2 (
        name VARCHAR(100) NOT NULL,
        age INT NOT NULL
    );

Quotation marks

It is a good practice to wrap up text related data in single quotes. If data contains single quotes, u can use escape sequences.

INSERT INTO shops (name) VALUES ('shoe emporium');

-- use escape sequence to include single quote in text value
INSERT INTO shops (name) VALUES ('mario\'s pizza');

INSERT INTO shops (name) VALUES ('she said "haha"');

DEFAULT values

CREATE TABLE cats3  (    
        name VARCHAR(20) DEFAULT 'no name provided',    
        age INT DEFAULT 99  
);

INSERT INTO cats3(age) VALUES(2);

INSERT INTO cats3() VALUES();

Having DEFAULT value for a column doesn’t guarantee that it can’t have NULL values. We can manually set NULL value for that column.

Combine NOT NULL and DEFAULT

CREATE TABLE cats4  (    
        name VARCHAR(20) NOT NULL DEFAULT 'unnamed',    
        age INT NOT NULL DEFAULT 99 
);

Primary Key

-- creating primary key for the table
-- this method is useful if primary key is based on single column
CREATE TABLE unique_cats (
    	cat_id INT PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        age INT
);

another option of specifying primary key :

-- creating primary key after all columns are specified
-- this option is useful if we have primary key of multiple columns
CREATE TABLE unique_cats2 (
    	cat_id INT,
        name VARCHAR(100),
        age INT,
        PRIMARY KEY (cat_id, name) 
);

Primary keys cannot be NULL. So it is redundant to specify NOT NULL for the columns that are part of primary key.

Primary key constraints are NOT NULL.

AUTO_INCREMENT

automatically increment for each row inserted into the table, starting with value 1 (by default).

CREATE TABLE unique_cats3 (
      cat_id INT AUTO_INCREMENT PRIMARY KEY,
      name VARCHAR(100) NOT NULL,
      age INT NOT NULL
);

To change default value for AUTO_INCREMENT :

ALTER TABLE <tablename> AUTO_INCREMENT = 100;

This statement alters the table’s AUTO_INCREMENT value to start from 100. Note that this statement will only affect future inserts into the table. If there are existing rows in the table with lower primary key values, they will not be modified. The next insert operation will use 100 as the starting value for the AUTO_INCREMENT column.


Exercise – Creating EMPLOYEES table

CREATE TABLE employees (
        id INT AUTO_INCREMENT,
        first_name VARCHAR(255) NOT NULL,
        last_name VARCHAR(255) NOT NULL,
        middle_name VARCHAR(255),
        age INT NOT NULL,
        current_status VARCHAR(255) NOT NULL DEFAULT 'employed',
        PRIMARY KEY(id)
);

-- inserting a row into the table
INSERT INTO employees(first_name, last_name, age) 
       VALUES ('Dora', 'Smith', 58);


Creating new Table and populating with Data

    DROP TABLE cats;

    -- creating a table
    CREATE TABLE cats (
        cat_id INT AUTO_INCREMENT,
        name VARCHAR(100),
        breed VARCHAR(100),
        age INT,
        PRIMARY KEY (cat_id)
    ); 

    -- populating data ino table
    INSERT INTO cats(name, breed, age) 
      VALUES ('Ringo', 'Tabby', 4),
             ('Cindy', 'Maine Coon', 10),
             ('Dumbledore', 'Maine Coon', 11),
             ('Egg', 'Persian', 4),
             ('Misty', 'Tabby', 13),
             ('George Michael', 'Ragdoll', 9),
             ('Jackson', 'Sphynx', 7);

    -- reading data from table
    -- To get all the columns
    SELECT * FROM cats;

    -- To only get the age column
    SELECT age FROM cats;

    -- To select multiple specific columns
    SELECT name, breed FROM cats;

WHERE Clause

-- Use where to specify a condition
SELECT * FROM cats WHERE age = 4;

SELECT * FROM cats WHERE name ='Egg';

By default, MySQL’s SELECT queries are case-insensitive for string comparisons. By default, MySQL uses a case-insensitive collation, such as utf8_general_ci (CI stands for case-insensitive) or utf8mb4_general_ci. In this case, string comparisons in SELECT queries are case-insensitive.

SELECT * FROM table_name WHERE column_name = 'apple';

This query would match rows with values ‘apple’, ‘Apple’, or ‘APPLE’.

If you need case-sensitive comparisons in your SELECT query, you can explicitly specify a case-sensitive collation, such as utf8_bin (BIN stands for binary).

SELECT * FROM table_name WHERE column_name COLLATE utf8_bin = 'apple';

This query would only match rows with the exact value ‘apple’, considering the case.

The case sensitivity behavior can also be defined at the column level. By specifying a case-sensitive collation for a specific column, you can override the default behavior for that column.

CREATE TABLE table_name (
    column_name VARCHAR(50) COLLATE utf8_bin
);

In this case, the column_name column would have a case-sensitive collation.

Aliases

Use ‘AS’ to alias a column in your results. It is used to rename column so that it is easier to understand.

SELECT cat_id AS id, name FROM cats;

UPDATE statement

Good Thumb rule – Test your WHERE clause with SELECT query before trying out with UPDATE / DELETE statements.

UPDATE cats SET breed='Shorthair' WHERE breed='Tabby';

UPDATE cats SET age=14 WHERE name='Misty';

-- More exercises

SELECT * FROM cats WHERE name='Jackson'; 
 
UPDATE cats SET name='Jack' WHERE name='Jackson'; 
 
SELECT * FROM cats WHERE name='Jackson'; 
 
SELECT * FROM cats WHERE name='Jack'; 
 
SELECT * FROM cats WHERE name='Ringo'; 
 
UPDATE cats SET breed='British Shorthair' WHERE name='Ringo'; 
 
SELECT * FROM cats WHERE name='Ringo'; 
 
SELECT * FROM cats; 

SELECT * FROM cats WHERE breed='Maine Coon'; 
 
UPDATE cats SET age=12 WHERE breed='Maine Coon'; 
 
SELECT * FROM cats WHERE breed='Maine Coon';

DELETE Statement

-- Delete all cats with name of 'Egg'
DELETE FROM cats WHERE name='Egg';

-- Delete all rows in the cats table
DELETE FROM cats;

In SQL, “TRUNCATE” and “DELETE” are two different commands used to remove data from database tables, but they function in distinct ways.

The TRUNCATE command is a Data Definition Language (DDL) operation used to quickly and efficiently remove all rows from a table. When you execute the TRUNCATE command, it removes all data from the specified table, but it retains the table structure and any associated indexes, triggers, or constraints.

TRUNCATE cannot be used on tables with foreign key constraints unless you disable or drop the constraints first.

Once executed, TRUNCATE cannot be undone, and the data cannot be recovered.

TRUNCATE TABLE table_name;

The DELETE command is a Data Manipulation Language (DML) operation used to remove specific rows from a table based on specified conditions. It allows you to selectively delete rows based on criteria such as a WHERE clause.

DELETE FROM table_name WHERE condition;

DELETE is slower than TRUNCATE since it logs each individual row deletion.

DELETE is a transactional operation that can be rolled back if executed within a transaction.

DELETE can be used with tables having foreign key constraints, and it can automatically handle cascading deletes if configured.

TRUNCATE is non-transactional, irreversible, and does not log individual deletions, while DELETE is transactional, reversible, and logs each row deletion.

Eclipse – for Java Development

What is Eclipse IDE

Eclipse is an Integrated Development Environment (IDE) that is widely used by developers for Java development, although it supports various other programming languages as well.

It offers a range of features and tools that make Java programming more efficient and productive. Here are some key features of Eclipse IDE for Java development:

  1. Code Editing: Eclipse provides a powerful code editor with features like syntax highlighting, code completion, and code templates. It also supports automatic formatting and refactoring to improve code readability and maintainability.
  2. Integrated Debugger: Eclipse includes a debugger that allows you to step through your code, set breakpoints, inspect variables, and analyze the flow of your program during runtime, helping you identify and fix bugs.
  3. Build and Compilation Tools: Eclipse integrates with build tools like Apache Maven and Ant, allowing you to manage dependencies, build projects, and run unit tests within the IDE. It also provides quick access to compile and run Java applications.
  4. Integrated Development Environment: Eclipse offers a comprehensive development environment with a project management system that organizes your Java projects, files, and resources. It supports version control systems like Git, enabling collaborative development.
  5. Plug-in Ecosystem: Eclipse is highly extensible through its plug-in architecture. It has a vast ecosystem of plugins, including those for additional language support, tools for testing, performance analysis, and integration with other frameworks and libraries.
  6. User Interface Design: Eclipse includes tools like WindowBuilder that allow you to design graphical user interfaces (GUIs) using drag-and-drop components. It supports various UI frameworks such as Swing, SWT, and JavaFX.
  7. Documentation and Help: Eclipse provides comprehensive documentation and online resources, including tutorials, user guides, and a vibrant community of developers who actively contribute to forums and provide support.

Eclipse IDE is known for its flexibility and scalability, making it suitable for both small projects and large enterprise applications. It offers a rich set of features specifically tailored to Java development, making it a popular choice among Java developers.

Installing Eclipse

Google for eclipse download and go to the link and download the installer.

https://www.eclipse.org/downloads/ – official link for downloading Eclipse software.

Instead of downloading installer file, go to packages section and download from there. Basically you will get a zip file which you can extract and gets the eclipse software.

Java 8 documentation –

https://docs.oracle.com/javase/8/docs/

–> ** Eclipse requires a compatible version of the Java Development Kit (JDK) to run. Make sure you have the JDK installed on your system. Set the PATH environment correctly to point to bin directory of the jdk installation.

ex : C:\Program Files\Java\jdk-1.8\bin

Check Eclipse binary and its pre-requisite Java versions.

Writing a Java Program in Eclipse

Here are the steps to write a Java program in Eclipse IDE:

  1. Launch Eclipse: Open the Eclipse IDE on your computer.
  2. Create a New Java Project: Go to “File” -> “New” -> “Java Project”. Enter a project name and click “Finish”.
  3. Create a New Java Class: Right-click on the project in the Package Explorer pane and select “New” -> “Class”. Enter a class name and click “Finish”.
  4. Write Java Code: In the newly created class file, you can start writing your Java code. For example, you can define the main method, which is the entry point of your program, as follows:
public class MyClass {
    public static void main(String[] args) {
        // Your code here
    }
}
  1. Write Your Java Code: Within the main method, you can write your Java code. This is where you define the logic of your program. You can use Eclipse’s code editor features, such as code completion, to assist you in writing code faster and with fewer errors.
  2. Save Your Java File: After writing your code, make sure to save the Java file by clicking “Ctrl + S” or going to “File” -> “Save”.
  3. Build and Run Your Program: To build and run your Java program, right-click within the editor area of the Java file and select “Run As” -> “Java Application” or click the “Run” button in the toolbar. Eclipse will compile your code, and the program will run in the console view or a separate console window, depending on your configuration.

That’s it! You have successfully written and executed a Java program in Eclipse IDE. You can continue to edit, build, and run your program as needed, and explore the various features and functionalities provided by Eclipse for Java development.

Setting up Java step by step tutorial

This is mainly for the beginners of Java to get started with Maven, and eclipse.

Set up folders

1) C:\tools to install Java development tools like JDK, Maven, Eclipse IDE, etc.
Create a sub-folder “jdk-8u131-windows-x64” to install JDK “8u131”.

2) C:\projects to store your Java projects.

3) C:\scripts to store any DOS or Unix scripts.

Pick your own folder. It could be under “C:\users\john\tools\java\jdk-8u131-windows-x64”, “C:\users\john\projects”, etc.

It is important to separate “tools“, “projects“, and “scripts“.

Install Java

Step 1: Download and install latest “Java SE Development Kit” (i.e. JDK) version “X” from

http://www.oracle.com/technetwork/java/javase/overview/index.html

by clicking on the “Downloads” tab. Select the “Java SE Platforms” and “Java” button.

Pick the Java SE Development Kit X Downloads, where “X” is the major version like 8, you will have the minor updates marked as say “u131“, etc.

Make sure that you download and install the right version for the operating system on which you will be running — for example Windows (32 bit or 64 bit), Linux, Solaris, MAC, etc. You will need both the JDK and the JRE.

Double click on the downloaded file “jdk-8u131-windows-x64.exe”, and follow the installation prompts and choose to change to “C:\tools\jdk-8u131-windows-x64” or whatever the folder you chose earlier.

Verify Java Installation

Step 1: Go to the installation folder, for example “C:\tools\jdk-8u131-windows-x64” to verify the presence of relevant files required for compiling & running Java.

The javac.exe is the compiler that converts a source file (e.g. HelloWorld.java) to a byte code file (e.g. HelloWorld.class). The java.exe is the run-time command to execute a program (i.e. java HelloWorld). The src.zip is where all the Java API (i.e. Java library) source (i.e. .java) files are located and rt.jar is where the Java API run-time class files (i.e. class) are located.

Java – JDBC example program

I had one usecase and for which I wrote this program. This program is compatible with JRE1.7.

The program makes a database connection using JDBC for oracle database and for every 200 milliseconds, it queries the database table for data. After 15 secs, the program exits.

TimerTask class used for running the sql query for every 200 milliseconds.

import java.sql.*;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;


public class OracleDBConnection extends TimerTask {
   Connection conn = null;
   Timer timer = null;
   Statement stmt = null;
   ResultSet rs = null;
   int count = 0;
   int period = 200; // interval period
   int iteration = 1;

   int duration = 15000; // duration in milliseconds

   public OracleDBConnection(Connection p_connection, Timer p_timer) {
       conn = p_connection;
       timer = p_timer;
   }

   public void run() {
      System.out.println("Code executed every 200 milliseconds : " + iteration);
      try {
         // Execute a SQL query using the existing connection
         stmt = conn.createStatement();
         rs = stmt.executeQuery("select * from <table> fetch first 2 rows only");

         // Process the query results
         while (rs.next()) {
            // Retrieve data from the query results
            String data = rs.getString("user_name");

           // Do something with the retrieved data
            System.out.println(data);
         }
      } catch (SQLException e) {
         e.printStackTrace();
      } finally {
         // Close the database resources
         try {
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
         } catch (SQLException e) {
            e.printStackTrace();
         }
      }
      iteration++;
      count++;
      if (count * period >= duration) {
         timer.cancel(); // stop the timer when duration is reached
         Date now = new Date();
         SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         formatter.setTimeZone(TimeZone.getDefault());
         String formattedDateTime = formatter.format(now);
         System.out.println("Completed DB query statements execution at time : " + formattedDateTime);
      }
   }
}

Main program that creates the connection and passes it to TimerTask object.

import java.util.TimeZone;
import java.text.SimpleDateFormat;

public class OracleDBConnectionTest {
    public static void main(String[] args) throws InterruptedException {
        Connection conn = null;
        String url = "jdbc:oracle:thin:@<connectionString>";
        String username = "username";
        String password = "password";

        try {

            Timer timer = new Timer();

            // Load the Oracle JDBC driver
            DriverManager.registerDriver (new oracle.jdbc.OracleDriver()) ;

            // Connect to the Oracle database
            conn = DriverManager.getConnection(url, username, password);

            // Create a TimerTask to execute the OracleDBConnection every 10 seconds
            TimerTask task = new OracleDBConnection(conn, timer);

            // Get current date and time in local time zone
            Date now = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            formatter.setTimeZone(TimeZone.getDefault());
            String formattedDateTime = formatter.format(now);

            System.out.println("Starting DB Query Statements at time : " + formattedDateTime);

            timer.schedule(task, 0, 200);

            Thread.sleep(20000);

            now = new Date();
            formattedDateTime = formatter.format(now);

            System.out.println("Exiting main program at time : " + formattedDateTime);

        } catch (SQLException e) {
            e.printStackTrace();

        } finally {
            // Close the database connection
            try {
                if (conn != null) {
                    System.out.println("Closing the connection");
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

Chef Adding a user to organization

In Chef, if you have created an organization and want to add user to that, here is the command :

sudo orc-server-ctl org-user-add <org> <user>

Check whether a particular user has access to an organization :

sudo knife raw /association_requests -s "https://<hostfqdn>/organizations/myorg" -u admin -k /home/abcd/.chef/admin.pem

Some of the commands related to org or user related :

org-create

    Create an organization in the Chef Infra Server.

  org-delete

    Delete an organization in the Chef Infra Server.

  org-list

    List all organizations in the Chef Infra Server.

  org-show

    Show an organization in the Chef Infra Server.

  org-user-add

    Associate a user with an organization.

  org-user-remove

    Dissociate a user with an organization.

  password

    Set a user’s password or System Recovery Password.

  user-create

    Create a user in the Chef Infra Server.

  user-delete

    Delete a user in the Chef Infra Server.

  user-edit

    Edit a user in the Chef Infra Server.

  user-list

    List all users in the Chef Infra Server.

  user-show

    Show a user in the Chef Infra Server.

Oracle Database – open resetlogs, redo logs

open resetlogs command

In Oracle database, the “open resetlogs” command is used to open a database

  • after performing incomplete recovery or
  • after restoring a backup of the database.

Suppose you have a database that was backed up at time T1. After the backup was taken, changes were made to the database up to time T2. Now suppose that due to some issue, the database became corrupt and you had to restore it from the T1 backup. To bring the database up to date with the changes made after the backup was taken, you perform a recovery operation using redo logs generated between T1 and T2.

Once the recovery operation is complete, you would use the “open resetlogs” command to indicate that the database should be opened with a new redo log file. Here is an example SQL statement that you would use to open the database with resetlogs:

SQL> ALTER DATABASE OPEN RESETLOGS;

This command would create a new redo log file, reset the online redo log sequence numbers to 1, and update the control file and data dictionary to indicate that the database is now open with the new redo log file. After executing this command, the database would be fully recovered and ready for use.

The “open resetlogs” command is used to indicate that the recovery operation is complete and that the database should be opened with a new redo log file.

The “open resetlogs” command performs the following actions:

  • It creates a new redo log file and resets the online redo log sequence numbers to 1.
  • It updates the control file to reflect the new log file sequence number.
  • It updates the data dictionary to indicate that the database is now open.

Note that the “open resetlogs” command should only be used after performing incomplete recovery or restoring a backup of the database. Using this command at any other time can result in data loss or corruption.

What are redologs ?

Imagine you are building a Lego castle, and as you build it, you keep a notebook where you write down all the pieces you use and where you put them. This way, if something goes wrong, you can look at your notebook and see what you did.

In a similar way, when you use a database like Oracle, the database keeps track of all the changes that are made to it in a file called a “redo log”. The redo log is like a notebook where the database writes down all the changes made to the database, such as adding new data, deleting data, or updating existing data.

The redo log is important because if something goes wrong with the database, such as a power failure or a software error, the database can use the redo log to “replay” all the changes made to the database since the last backup. This way, the database can recover all the changes that were made and bring itself up to date, just like you can use your notebook to rebuild your Lego castle if something goes wrong.

As changes are made to the database, the database writes the changes to the redo log files in a circular fashion. When the redo log file is full, the database switches to the next redo log file and continues writing changes to it. This process continues until all the redo log files have been used, at which point the database goes back to the beginning of the first redo log file and starts overwriting the oldest changes.

redo logs in an Oracle database are stored on disk in a location specified by the database administrator, and they are written to in a circular fashion as changes are made to the database.

In summary, the redo log is a file that keeps track of all the changes made to a database, and it is used to recover changes if something goes wrong with the database.

Perl Dumper

In Perl, you can use the Data::Dumper module to dump data structures into a string. Here’s an example:

use Data::Dumper;

my $data = { 
    name => 'John Doe',
    age => 35,
    hobbies => ['reading', 'swimming', 'traveling'],
};

my $string = Dumper($data);
print $string;

The output of this code will be a string representation of the data structure:

$VAR1 = {
          'name' => 'John Doe',
          'hobbies' => [
                         'reading',
                         'swimming',
                         'traveling'
                       ],
          'age' => 35
        };

You can also use the Dumper() function to dump other types of data structures, such as arrays or scalars.

Reference Udemy courses

Scrum

https://www.udemy.com/course-dashboard-redirect/?course_id=2809631

C

https://www.udemy.com/course-dashboard-redirect/?course_id=2800976 – Advanced C Programming

https://www.udemy.com/course-dashboard-redirect/?course_id=3408682 – Pointers and Memory management

C++

https://www.udemy.com/course-dashboard-redirect/?course_id=2987082 – C++20 Masterclass

https://www.udemy.com/course-dashboard-redirect/?course_id=3515300 – Mastering 4 critical skills

https://www.udemy.com/course-dashboard-redirect/?course_id=1706344 – C++ step by step

Project Management

https://www.udemy.com/course-dashboard-redirect/?course_id=2132982 – Manage ur IT Project

Perl

https://www.udemy.com/course-dashboard-redirect/?course_id=965166