Dot Java

Java Basics

Explore the fundamental concepts of the Java programming language, including data types, variables, operators, control structures, and methods.

Data Types

Different data types in Java such as int, double, boolean, and String, allow you to store various kinds of data.

int x = 10;
double y = 3.14;
boolean isTrue = true;
String name = "John Doe";
The variables x, y, isTrue, and name are initialized with values 10, 3.14, true, and "John Doe", respectively.

This code snippet demonstrates the declaration and initialization of variables with different data types: an integer, a double, a boolean, and a string.

Variables

Variables in Java store data values that can be used and manipulated throughout the program.

int age = 25;
String city = "New York";
double salary = 50000.0;
The variables age, city, and salary are initialized with values 25, "New York", and 50000.0, respectively.

This code shows how to declare variables of various types and initialize them with values. Variables store data that can be used and manipulated throughout the program.

Operators

Operators in Java are special symbols used to perform operations on variables and values.

int a = 10;
int b = 5;
int sum = a + b;
int diff = a - b;
int product = a * b;
int quotient = a / b;
The variables sum, diff, product, and quotient are calculated as 15, 5, 50, and 2, respectively.

This example demonstrates the use of arithmetic operators in Java. It shows how to perform basic mathematical operations like addition, subtraction, multiplication, and division.

Control Structures

Control structures like if-else, switch-case, and loops determine the flow of execution in a Java program.

int num = 10;
if (num > 0) {
  System.out.println("Positive number");
} else {
  System.out.println("Non-positive number");
}

switch (num) {
  case 1:
    System.out.println("One");
    break;
  case 10:
    System.out.println("Ten");
    break;
  default:
    System.out.println("Other number");
}

for (int i = 0; i < 5; i++) {
  System.out.println(i);
}
Output:
Positive number
Ten
0
1
2
3
4

This snippet demonstrates the use of control structures in Java. The if-else statement checks if a number is positive. The switch-case statement executes different code blocks based on the value of the number. The for loop iterates from 0 to 4 and prints each value.

Methods

Methods in Java are blocks of code that perform a specific task and can be called upon when needed.

public class Main {
  public static void main(String[] args) {
    greet("John");
  }

  public static void greet(String name) {
    System.out.println("Hello, " + name);
  }
}
Output:
Hello, John

This code defines a class with a main method that calls another method named greet. The greet method takes a string parameter and prints a greeting message. Methods help organize code into reusable blocks.

Java Object-Oriented Programming

Dive into the principles of object-oriented programming in Java, including classes, objects, inheritance, and encapsulation.

Classes and Objects

Classes are blueprints for creating objects, which are instances of classes containing attributes and methods.

class Person {
  String name;
  int age;

  void introduce() {
    System.out.println("Hello, my name is " + name);
  }
}

Person p = new Person();
p.name = "John";
p.age = 30;
p.introduce();
Output:
Hello, my name is John

This example defines a class named Person with two fields (name and age) and a method (introduce). An object of the Person class is created, its fields are assigned values, and the introduce method is called to print a message.

Inheritance

Inheritance allows one class to inherit fields and methods from another class, promoting code reuse and organization.

class Employee extends Person {
  double salary;

  void displaySalary() {
    System.out.println("Salary: " + salary);
  }
}

Employee e = new Employee();
e.name = "John";
e.age = 35;
e.salary = 50000.0;
e.introduce();
e.displaySalary();
Output:
Hello, my name is John
Salary: 50000.0

This code demonstrates inheritance, where the Employee class inherits from the Person class. The Employee class has an additional field (salary) and a method (displaySalary). An object of the Employee class is created and methods from both the Employee and Person classes are called.

Encapsulation

Encapsulation restricts direct access to certain components of an object, promoting modularity and maintainability.

class BankAccount {
  private double balance;

  public void deposit(double amount) {
    balance += amount;
  }

  public void withdraw(double amount) {
    if (balance >= amount) {
      balance -= amount;
    } else {
      System.out.println("Insufficient funds.");
    }
  }

  public double getBalance() {
    return balance;
  }
}

BankAccount account = new BankAccount();
account.deposit(1000.0);
account.withdraw(500.0);
System.out.println("Balance: " + account.getBalance());
Output:
Balance: 500.0

This example illustrates encapsulation, where the BankAccount class's balance field is private and can only be accessed through public methods (deposit, withdraw, getBalance). This ensures that the balance cannot be directly modified from outside the class.

Polymorphism

Polymorphism allows objects of different classes to be treated as objects of a common super class, enhancing flexibility and integration.

class Animal {
  void sound() {
    System.out.println("Animal makes a sound");
  }
}

class Dog extends Animal {
  void sound() {
    System.out.println("Dog barks");
  }
}

class Cat extends Animal {
  void sound() {
    System.out.println("Cat meows");
  }
}

Animal a1 = new Dog();
Animal a2 = new Cat();
a1.sound(); // Dog barks
a2.sound(); // Cat meows
Output:
Dog barks
Cat meows

This code demonstrates polymorphism, where a single interface (Animal) can be used for different types (Dog and Cat). The sound method is overridden in Dog and Cat classes, and when called, the appropriate method for the actual object type is executed.

Interfaces

Interfaces in Java are abstract types that allow classes to implement multiple inheritance-like structures.

interface Animal {
  void makeSound();
}

class Dog implements Animal {
  public void makeSound() {
    System.out.println("Bark");
  }
}

class Cat implements Animal {
  public void makeSound() {
    System.out.println("Meow");
  }
}

public class Main {
  public static void main(String[] args) {
    Animal dog = new Dog();
    Animal cat = new Cat();
    dog.makeSound(); // Bark
    cat.makeSound(); // Meow
  }
}
Output:
Bark
Meow

This example demonstrates how to define an interface and implement it in multiple classes. The Animal interface has a single method, makeSound, which is implemented differently in Dog and Cat classes.

Abstract Classes and Methods

Abstract classes and methods define a template for other classes to extend and provide concrete implementations.

abstract class Animal {
  abstract void makeSound();

  public void sleep() {
    System.out.println("Sleeping...");
  }
}

class Dog extends Animal {
  public void makeSound() {
    System.out.println("Bark");
  }
}

class Cat extends Animal {
  public void makeSound() {
    System.out.println("Meow");
  }
}

public class Main {
  public static void main(String[] args) {
    Animal dog = new Dog();
    Animal cat = new Cat();
    dog.makeSound(); // Bark
    cat.makeSound(); // Meow
    dog.sleep();     // Sleeping...
    cat.sleep();     // Sleeping...
  }
}
Output:
Bark
Meow
Sleeping...
Sleeping...

This example demonstrates how to use abstract classes and methods. The Animal class is abstract and includes an abstract method makeSound that must be implemented by any subclass. It also includes a regular method sleep that can be used by all subclasses.

Constructors

Constructors in Java initialize new objects and set initial values for fields.

class Person {
  String name;
  int age;

  // Default constructor
  public Person() {
    this.name = "Unknown";
    this.age = 0;
  }

  // Parameterized constructor
  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
}

public class Main {
  public static void main(String[] args) {
    Person p1 = new Person(); // Calls default constructor
    Person p2 = new Person("Alice", 30); // Calls parameterized constructor
    System.out.println(p1.name + " is " + p1.age + " years old.");
    System.out.println(p2.name + " is " + p2.age + " years old.");
  }
}
Output:
Unknown is 0 years old.
Alice is 30 years old.

This code demonstrates how to define default and parameterized constructors in a class. The default constructor initializes fields to default values, while the parameterized constructor sets them based on provided arguments.

Java Standard Library

Explore the most commonly used Java standard library classes and their usage, including collections, I/O, and more.

Collections

Collections in Java provide a framework for storing and manipulating groups of objects.

List<String> names = new ArrayList<>();
names.add("John");
names.add("Jane");
names.add("Bob");

Set<Integer> numbers = new HashSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);

Map<String, Integer> ages = new HashMap<>();
ages.put("John", 30);
ages.put("Jane", 25);
ages.put("Bob", 35);
ArrayList names contains: ["John", "Jane", "Bob"]
HashSet numbers contains: [1, 2, 3]
HashMap ages contains: {"John"=30, "Jane"=25, "Bob"=35}

This example demonstrates the usage of Java collections. An ArrayList is used to store a list of names, a HashSet is used to store unique numbers, and a HashMap is used to store key-value pairs of names and ages.

I/O

Java's I/O (Input/Output) classes are used to read data from and write data to files and other input and output sources.

try {
  FileWriter writer = new FileWriter("output.txt");
  writer.write("Hello, World!");
  writer.close();
} catch (IOException e) {
  System.out.println("An error occurred.");
  e.printStackTrace();
}

try {
  FileReader reader = new FileReader("input.txt");
  // Read operations
} catch (FileNotFoundException e) {
  System.out.println("An error occurred.");
  e.printStackTrace();
}
Output to file "output.txt" contains: Hello, World!

This code snippet shows basic file I/O operations in Java. A FileWriter is used to write text to a file, and a FileReader (commented) is used to read text from a file. Exception handling ensures that any I/O errors are caught and handled appropriately.

Networking

Java's networking classes allow you to communicate with other computers over a network using sockets and other protocols.

try {
  Socket socket = new Socket("example.com", 80);
  PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
  BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  out.println("GET / HTTP/1.1\nHost: example.com\n\n");
  String response = in.readLine();
  while (response != null) {
    System.out.println(response);
    response = in.readLine();
  }
  socket.close();
} catch (IOException e) {
  System.out.println("An error occurred.");
  e.printStackTrace();
}
Output:
HTTP/1.1 200 OK
Content-Type: text/html
...
(The response lines continue until the end of the response body)

This example demonstrates basic networking in Java. A socket connection is established to a web server, an HTTP GET request is sent, and the server's response is read and printed line by line. Proper exception handling ensures that any networking errors are caught and handled.

Concurrency

Java's concurrency utilities enable parallel execution of code using threads and synchronization.

class MyThread extends Thread {
  public void run() {
    System.out.println("Thread running");
  }
}

MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start();
t2.start();
Output:
Thread running
Thread running
(The order of the output may vary)

This code demonstrates concurrency in Java using threads. A custom thread class is created by extending the Thread class and overriding the run method. Two threads are instantiated and started, running concurrently and printing a message.

Date and Time

Java's date and time API provides classes for managing dates, times, and durations.

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;

LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();

System.out.println("Date: " + date);
System.out.println("Time: " + time);
System.out.println("DateTime: " + dateTime);
Output:
Date: 2024-06-20
Time: 14:35:50.123
DateTime: 2024-06-20T14:35:50.123

This example shows how to work with date and time using the java.time package. It retrieves and prints the current date, time, and date-time using LocalDate, LocalTime, and LocalDateTime classes, respectively.

Advanced Java

Explore advanced topics in Java, including generics, lambda expressions, streams, and more.

Generics

Generics enable types (classes and methods) to operate on objects of various types while providing compile-time type safety.

class Box<T> {
  private T value;

  public void setValue(T value) {
    this.value = value;
  }

  public T getValue() {
    return value;
  }
}

Box<Integer> intBox = new Box<>();
intBox.setValue(10);
System.out.println("Integer Value: " + intBox.getValue());

Box<String> strBox = new Box<>();
strBox.setValue("Hello");
System.out.println("String Value: " + strBox.getValue());
Output:
Integer Value: 10
String Value: Hello

This example demonstrates the use of generics in Java, which allow classes, interfaces, and methods to operate on types specified by the programmer. The Box class can store any type of value, and two instances of Box are created to store an Integer and a String.

Lambda Expressions

Lambda expressions provide a clear and concise way to represent one method interface using an expression.

List<String> names = Arrays.asList("John", "Jane", "Bob");

names.forEach(name -> System.out.println(name));
Output:
John
Jane
Bob

This code demonstrates the use of lambda expressions in Java. The forEach method of the List interface is used to iterate over the list of names and print each name. Lambda expressions provide a concise way to represent anonymous functions.

Streams

Streams support functional-style operations on sequences of elements, such as map-reduce transformations.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

int sum = numbers.stream()
  .filter(n -> n % 2 == 0)
  .mapToInt(Integer::intValue)
  .sum();

System.out.println("Sum of even numbers: " + sum);
Output:
Sum of even numbers: 6

This example demonstrates the use of streams in Java to process a list of integers. The stream pipeline filters even numbers, converts them to integers, and calculates their sum. Streams allow for functional-style operations on collections of objects.

Annotations

Annotations provide metadata about the program, which can be used by the compiler or at runtime.

@Override
public String toString() {
  return "Custom toString implementation";
}

@SuppressWarnings("unchecked")
public void myMethod() {
  List rawList = new ArrayList();
  rawList.add("Test");
}
Output:
Method toString() returns: Custom toString implementation
Method myMethod() suppresses unchecked warnings.

This code demonstrates the use of annotations in Java. The @Override annotation indicates that a method is overriding a superclass method. The @SuppressWarnings annotation is used to suppress compiler warnings, in this case, unchecked type operations.

Reflection

Reflection allows inspection and manipulation of classes, methods, and fields at runtime.

try {
  Class<?> clazz = Class.forName("java.lang.String");
  Method method = clazz.getMethod("substring", int.class, int.class);
  String str = "Hello, World!";
  String result = (String) method.invoke(str, 7, 12);
  System.out.println("Result: " + result);
} catch (Exception e) {
  e.printStackTrace();
}
Output:
Result: World

This code demonstrates the use of reflection in Java to inspect and manipulate classes at runtime. The Class.forName method retrieves the String class, the getMethod method retrieves the substring method, and the method.invoke method calls substring on the given string.

Enums

Enums are special Java types used to define collections of constants.

enum Day {
  SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

public class Main {
  public static void main(String[] args) {
    Day today = Day.MONDAY;
    switch (today) {
      case MONDAY:
        System.out.println("Today is Monday");
        break;
      case FRIDAY:
        System.out.println("Today is Friday");
        break;
      default:
        System.out.println("Another day");
    }
  }
}
Output:
Today is Monday

This example shows how to define and use an enum. The Day enum represents the days of the week, and a switch statement is used to print a message based on the current day.

Records

Records provide a compact syntax for declaring classes that are primarily used to store data.

public record Person(String name, int age) {}

public class Main {
  public static void main(String[] args) {
    Person person = new Person("John", 25);
    System.out.println(person.name() + " is " + person.age() + " years old.");
  }
}
Output:
John is 25 years old.

This example shows how to define and use a record in Java. Records provide a compact syntax for declaring classes that are primarily used to store data and automatically generate common methods like constructors, equals, hashCode, and toString.