Showing posts with label Oracle Java. Show all posts
Showing posts with label Oracle Java. Show all posts

Friday, June 28, 2024

Finding a Key’s Index in Java LinkedHashMap

Finding a Key’s Index in Java LinkedHashMap

The Java LinkedHashMap class combines a hash table and linked list to maintain predictable iteration order, unlike HashMap. However, LinkedHashMap does not provide a direct method to get the position (index) of a key-value pair. This article explores methods to retrieve the index of a key-value pair in a LinkedHashMap.

1. Using Iteration


One straightforward method is to iterate through the entrySet of the LinkedHashMap, comparing each key with the target key and returning the index when a match is found.

LinkedHashMapIterationApproach.java

public class LinkedHashMapIteration {
 
    public static void main(String[] args) {
         
        // Create a LinkedHashMap with Integer keys and String values
        LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put(101, "Alice");
        linkedHashMap.put(202, "Bob");
        linkedHashMap.put(303, "Charlie");
        linkedHashMap.put(404, "David");
 
        // Key to find position for
        Integer key = 303;
         
        // Find the position of the key using iteration approach
        int position = getPositionOfKey(linkedHashMap, key);
         
        // Output the result
        System.out.println("LinkedHashMap: " + linkedHashMap);
        System.out.println("Finding position of key: " + key);
        System.out.println("Position: " + position);
        //System.out.println("The position of the key \"" + key + "\" is: " + position);
    }
 
    public static <K, V> int getPositionOfKey(LinkedHashMap<K, V> map, K key) {
        int index = 0;
        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (entry.getKey().equals(key)) {
                return index;
            }
            index++;
        }
        return -1; // Key not found
    }
}

Output:

LinkedHashMap: {101=Alice, 202=Bob, 303=Charlie, 404=David}
Finding position of key: 303
Position: 2

In this example, we create a LinkedHashMap<Integer, String> and populate it with key-value pairs. Next, we specify key = 303 to demonstrate finding the position of the key 303. The getPositionOfKey method iterates through the entrySet() of the LinkedHashMap and compares each key with key. Upon finding a match (key = 303), it returns the position (index) 2 since indexing starts from 0.

2. Using Key Set Conversion


Using this approach, we convert the key set to a list and then find the index of the key.

LinkedHashMapKeySetConversion.java

public class LinkedHashMapKeySetConversion {
 
    public static void main(String[] args) {
        LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("January", 1);
        linkedHashMap.put("February", 2);
        linkedHashMap.put("March", 3);
        linkedHashMap.put("April", 4);
 
        String key = "January";
        int position = getPositionOfKey(linkedHashMap, key);
        System.out.println("The position of the key \"" + key + "\" is: " + position);
    }
 
    public static <K, V> int getPositionOfKey(LinkedHashMap<K, V> map, K key) {
        List<K> keyList = new ArrayList<>(map.keySet());
        return keyList.indexOf(key);
    }
}

Here, the keySet of the LinkedHashMap is converted to an ArrayList. The indexOf method of ArrayList is then used to find the index of the key.

Output:

The position of the key "January" is: 0

3. Using Stream API (Java 8+)


With Java 8 and higher, the Stream API offers a straightforward way to solve this issue using functional programming principles.

LinkedHashMapStreamApiApproach.java

public class LinkedHashMapStreamApiApproach {
 
    public static int findKeyPosition(LinkedHashMap<String, Integer> map, String key) {
        int position = 0;
        Optional<String> foundKey = map.entrySet().stream()
                .filter(entry -> entry.getKey().equals(key))
                .map(Map.Entry::getKey)
                .findFirst();
 
        if (foundKey.isPresent()) {
            // Key found, iterate again to count position
            for (Map.Entry<String, Integer> entry : map.entrySet()) {
                if (entry.getKey().equals(key)) {
                    return position;
                }
                position++;
            }
        }
        return -1; // Key not found
    }
 
    public static void main(String[] args) {
         
        LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
        map.put("apple", 10);
        map.put("banana", 20);
        map.put("cherry", 30);
 
        int position = findKeyPosition(map, "banana");
 
        if (position != -1) {
            System.out.println("Key 'banana' found at position: " + position);
        } else {
            System.out.println("Key 'banana' not found");
        }
    }
}

In this approach, we use entrySet().stream() to create a Stream of key-value pairs from the map and use filter to filter the stream to keep only entries where the key matches the target key. We use map(Map.Entry::getKey) is to extract just the keys from the filtered entries and use findFirst to retrieve the first matching key wrapped in an Optional. If the Optional contains a value (meaning the key was found), we iterate through the entire entrySet again.

Inside the loop, we compare the current entry’s key with the target key. If there’s a match, we return the current position as it represents the target key’s position based on insertion order.

4. Using keySet() and List.copyOf() (Java 10+)


This approach leverages the List.copyOf() method to create a list from the key set and then find the index of the key.

LinkedHashMapListCopyOf.java

public class LinkedHashMapListCopyOf {
 
    public static void main(String[] args) {
        LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("apple", 10);
        linkedHashMap.put("banana", 20);
        linkedHashMap.put("cherry", 30);
        linkedHashMap.put("orange", 40);
 
        String key = "orange";
        int position = getPositionOfKey(linkedHashMap, key);
        System.out.println("The position of the key \"" + key + "\" is: " + position);
    }
 
    public static <K, V> int getPositionOfKey(LinkedHashMap<K, V> map, K key) {
        List<K> keyList = List.copyOf(map.keySet());
        return keyList.indexOf(key);
    }
}

In this approach, List.copyOf(map.keySet()) method creates an unmodifiable copy of the key set from the LinkedHashMap and we use keyList.indexOf(key method to return the index of the specified key in the list. The output is:

The Posotion of the key "orange" is: 3

Example Output Using List.copyOf for Java LinkedHashMap Key Position

5. Conclusion

In this article, we explored several methods to find the position of a key-value pair in a Java LinkedHashMap. We began with a straightforward iteration approach, followed by converting the key set to a list for direct index retrieval. We also demonstrated the power of Java 8’s Stream API for a more functional programming solution. Additionally, we leveraged Java 10’s List.copyOf() method to create an unmodifiable list from the key set, facilitating easy position finding. Each method showcases different aspects of Java’s rich API and highlights various ways to achieve the same goal.

Source: javacodegeeks.com

Monday, June 24, 2024

Easily install Oracle Java on Oracle Linux in OCI: It’s a perfect match!

Throughout its decades-long history, Oracle Java has constantly evolved to keep up with the growing demands of business-critical performance and scalability. Being a simple yet robust and secure programming language, Java enables millions of developers to craft portable applications for embedded systems, mobiles, and the cloud. Oracle Java is the #1 programming language and development platform, helping enterprises worldwide rapidly innovate and improve the performance and stability of their application services.

Oracle’s proven Java Development Kit (JDK), Oracle Java SE, allows developers to write more stable and secure applications with shortened development timeframes and reduced costs. With its modern and architecture-neutral approach, Oracle Java fits into all types of technology stacks, making it one of the strongest contenders to be used for DevOps and cloud development. For microservices and other containerized workloads, Oracle GraalVM provides more optimization options for cloud native applications, including ahead-of-time compilation to reduce memory and CPU usage.

Oracle Java on OCI


For Oracle Cloud Infrastructure (OCI) customers, an OCI subscription includes licenses and full support for all Oracle Java SE and Oracle GraalVM versions at no extra cost. OCI customers can even monitor and manage the use of Java in their enterprise with the Java Management Service (JMS), a reporting and management infrastructure integrated with OCI platform services. With JMS, Java users can monitor Java deployments on OCI instances and instances running on-premises in data centers, helping gain insights into Java application behavior, performance, and compliance.

Oracle Java is supported on Oracle’s long-standing and highly performant operating system, Oracle Linux. Oracle Linux is compatible with 64-bit Intel/AMD (x86-64) and 64-bit Arm (aarch64) processors, enabling applications to be quickly created, deployed, and used across a range of platforms. Moreover, because Oracle Linux is supported across on-premises and multicloud infrastructures and is optimized out of the box for Oracle software, it’s the ideal operating system on which to run Oracle Java.

Compute instances on OCI have access to a regional Oracle Linux yum server mirror for high-speed access to RPMs, which makes it easy to install Oracle Java and Oracle GraalVM. Take advantage of our tutorial to learn how you can use RPMs available from the OCI yum service to easily install Oracle Java on an Oracle Linux system running on OCI.

While installation on Oracle Linux is simple and straightforward, to make it even easier for developers to get started, OCI offers the Oracle Linux Cloud Developer image, which is available as a platform image.

Begin developing with the Oracle Linux Cloud Developer image in minutes


The Oracle Linux Cloud Developer image is a ready-to-run image that preinstalls and launches a comprehensive cloud development environment that includes various popular development languages such as Java with Oracle JDK or Oracle GraalVM, Python, Ruby, and more. Tooling for working with OCI, such as software developer kits (SDKs), CLIs, and Oracle Database connectors, are also included.

With the Oracle Linux Cloud Developer image, you don’t have to go through the typical installation process for development tools. Simply select the image when provisioning your OCI instance.

Easily install Oracle Java on Oracle Linux in OCI: It’s a perfect match!

When your instance is provisioned, jump straight into building applications.

Source: oracle.com

Friday, May 17, 2024

Oracle Java Time Range Check: Comprehensive Guide

Oracle Java Time Range Check: Comprehensive Guide

Oracle Java offers a multitude of functionalities for time and date manipulation, essential for developing robust and reliable applications. Among these functionalities, time range checks are pivotal for ensuring that events occur within specified boundaries. This comprehensive guide delves into the intricacies of implementing time range checks in Oracle Java, providing detailed insights and practical examples to help developers master this essential task.

Understanding Time in Oracle Java


Java's time and date API has evolved significantly, especially with the introduction of the java.time package in Java 8, also known as the new Date-Time API. This package addresses many of the issues present in the previous versions and provides a more comprehensive and flexible framework for handling time.

The Importance of the java.time Package


The java.time package simplifies time operations by offering clear and intuitive classes like LocalTime, LocalDate, LocalDateTime, and ZonedDateTime. These classes provide methods to easily manipulate and compare time values.

Key Classes for Time Range Checks:

  • LocalTime: Represents a time without a date, such as 10:15:30.
  • LocalDate: Represents a date without a time, such as 2024-05-17.
  • LocalDateTime: Combines date and time, such as 2024-05-17T10:15:30.
  • ZonedDateTime: A date-time with a time-zone in the ISO-8601 calendar system, such as 2024-05-17T10:15:30+01:00[Europe/Paris].

Implementing Time Range Checks


Basic Time Range Check with LocalTime

To check if a given time falls within a specific range, LocalTime is typically used. Here’s an example demonstrating a basic time range check:

import java.time.LocalTime;

public class TimeRangeCheck {
    public static void main(String[] args) {
        LocalTime startTime = LocalTime.of(9, 0);
        LocalTime endTime = LocalTime.of(17, 0);
        LocalTime currentTime = LocalTime.now();

        if (currentTime.isAfter(startTime) && currentTime.isBefore(endTime)) {
            System.out.println("Current time is within the range.");
        } else {
            System.out.println("Current time is outside the range.");
        }
    }
}

Time Range Check with LocalDateTime

For scenarios requiring date and time, LocalDateTime is more appropriate. Here’s an example:

import java.time.LocalDateTime;

public class DateTimeRangeCheck {
    public static void main(String[] args) {
        LocalDateTime startDateTime = LocalDateTime.of(2024, 5, 17, 9, 0);
        LocalDateTime endDateTime = LocalDateTime.of(2024, 5, 17, 17, 0);
        LocalDateTime currentDateTime = LocalDateTime.now();

        if (currentDateTime.isAfter(startDateTime) && currentDateTime.isBefore(endDateTime)) {
            System.out.println("Current date and time are within the range.");
        } else {
            System.out.println("Current date and time are outside the range.");
        }
    }
}

Advanced Time Range Check with ZonedDateTime

When dealing with multiple time zones, ZonedDateTime ensures that the checks consider the time zone differences. Below is an example of how to perform a time range check with ZonedDateTime:

import java.time.ZonedDateTime;
import java.time.ZoneId;

public class ZonedDateTimeRangeCheck {
    public static void main(String[] args) {
        ZonedDateTime startZonedDateTime = ZonedDateTime.of(2024, 5, 17, 9, 0, 0, 0, ZoneId.of("Europe/Paris"));
        ZonedDateTime endZonedDateTime = ZonedDateTime.of(2024, 5, 17, 17, 0, 0, 0, ZoneId.of("Europe/Paris"));
        ZonedDateTime currentZonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));

        if (currentZonedDateTime.isAfter(startZonedDateTime) && currentZonedDateTime.isBefore(endZonedDateTime)) {
            System.out.println("Current zoned date and time are within the range.");
        } else {
            System.out.println("Current zoned date and time are outside the range.");
        }
    }
}

Handling Edge Cases in Time Range Checks


Midnight Crossings

One common edge case is when the time range crosses midnight, such as from 10 PM to 2 AM. This scenario requires special handling to avoid incorrect range checks:

import java.time.LocalTime;

public class MidnightCrossingCheck {
    public static void main(String[] args) {
        LocalTime startTime = LocalTime.of(22, 0); // 10 PM
        LocalTime endTime = LocalTime.of(2, 0); // 2 AM
        LocalTime currentTime = LocalTime.now();

        boolean isInRange;
        if (startTime.isAfter(endTime)) {
            isInRange = !currentTime.isBefore(startTime) || !currentTime.isAfter(endTime);
        } else {
            isInRange = !currentTime.isBefore(startTime) && !currentTime.isAfter(endTime);
        }

        if (isInRange) {
            System.out.println("Current time is within the midnight-crossing range.");
        } else {
            System.out.println("Current time is outside the midnight-crossing range.");
        }
    }
}

Inclusive vs. Exclusive Range Boundaries

In some applications, the range boundaries might be inclusive or exclusive. Adjusting the check to include or exclude the boundary times ensures the correct behavior:

import java.time.LocalTime;

public class InclusiveExclusiveRangeCheck {
    public static void main(String[] args) {
        LocalTime startTime = LocalTime.of(9, 0);
        LocalTime endTime = LocalTime.of(17, 0);
        LocalTime currentTime = LocalTime.now();

        boolean isInclusive = true;

        boolean isInRange;
        if (isInclusive) {
            isInRange = !currentTime.isBefore(startTime) && !currentTime.isAfter(endTime);
        } else {
            isInRange = currentTime.isAfter(startTime) && currentTime.isBefore(endTime);
        }

        if (isInRange) {
            System.out.println("Current time is within the range.");
        } else {
            System.out.println("Current time is outside the range.");
        }
    }
}

Practical Applications of Time Range Checks


Oracle Java Time Range Check: Comprehensive Guide
Scheduling Systems

Time range checks are fundamental in scheduling systems to ensure that appointments or tasks are set within acceptable hours. For instance, booking systems often restrict the booking times to business hours:

import java.time.LocalTime;

public class BookingSystem {
    public static void main(String[] args) {
        LocalTime businessStartTime = LocalTime.of(9, 0);
        LocalTime businessEndTime = LocalTime.of(17, 0);
        LocalTime requestedTime = LocalTime.of(15, 0); // Example booking time

        if (requestedTime.isAfter(businessStartTime) && requestedTime.isBefore(businessEndTime)) {
            System.out.println("Booking time is within business hours.");
        } else {
            System.out.println("Booking time is outside business hours.");
        }
    }
}

Access Control

Time-based access control systems use time range checks to grant or deny access based on the current time. For example, employees might have access to a building only during their shift hours:

import java.time.LocalTime;

public class AccessControl {
    public static void main(String[] args) {
        LocalTime shiftStartTime = LocalTime.of(8, 0);
        LocalTime shiftEndTime = LocalTime.of(18, 0);
        LocalTime accessTime = LocalTime.now();

        if (accessTime.isAfter(shiftStartTime) && accessTime.isBefore(shiftEndTime)) {
            System.out.println("Access granted.");
        } else {
            System.out.println("Access denied.");
        }
    }
}

Conclusion

Time range checks in Oracle Java are essential for ensuring that events and operations occur within designated time frames. Utilizing the java.time package, developers can efficiently implement time range checks for various applications, from scheduling systems to access control mechanisms. By understanding and applying the principles and techniques outlined in this guide, you can ensure accurate and reliable time-based operations in your Java applications.

Friday, April 19, 2024

Understanding the Distinction: Oracle Java vs. Java

Understanding the Distinction: Oracle Java vs. Java

In the realm of programming languages, clarity is paramount. Yet, the distinction between Oracle Java and Java itself can often be a source of confusion for many. Let us delve into the nuances and clarify the differences between these two entities, shedding light on their unique characteristics and functionalities.

The Origins of Java


Java, conceived by James Gosling at Sun Microsystems in the early 1990s, revolutionized the world of software development with its platform independence and object-oriented structure. It was designed to be versatile, robust, and secure, catering to a wide array of applications across various platforms.

Evolution into Oracle Java


With Oracle's acquisition of Sun Microsystems in 2010, Java underwent a transition, leading to the emergence of Oracle Java. Oracle, a global technology powerhouse, assumed stewardship of the Java platform, further enhancing its development and support infrastructure.

Key Differentiators


Ownership and Licensing

One of the primary distinctions between Java and Oracle Java lies in their ownership and licensing models. While Java was initially developed by Sun Microsystems and later maintained by Oracle Corporation, Oracle Java specifically refers to the version of Java distributed by Oracle under its own licensing agreements.

Support and Updates

Oracle Java offers comprehensive support and regular updates through Oracle's robust infrastructure, ensuring the security, stability, and optimization of the platform. This includes timely patches for vulnerabilities and compatibility enhancements to keep Java applications running smoothly.

Enterprise Focus

Oracle Java is tailored to meet the demands of enterprise-level applications, providing advanced features, tools, and services optimized for large-scale deployments. Enterprises benefit from Oracle's extensive resources and expertise in managing complex software ecosystems.

Community Engagement

While both Java and Oracle Java have vibrant developer communities, Oracle Java enjoys the backing of Oracle's extensive network of developers, contributors, and partners. This fosters collaboration, innovation, and knowledge sharing within the ecosystem, driving the evolution of the platform.

Compatibility and Interoperability


Java, in its essence, remains a universally compatible language, adhering to the "write once, run anywhere" principle. Similarly, Oracle Java maintains this compatibility while also offering seamless integration with Oracle's extensive suite of enterprise technologies, such as databases, middleware, and cloud services.

Conclusion

In conclusion, while Oracle Java and Java share a common lineage, they represent distinct entities within the realm of programming languages. Oracle Java builds upon the foundation laid by Java, offering enhanced features, support, and compatibility tailored for enterprise-grade applications. Understanding the nuances between the two is essential for developers, businesses, and enthusiasts alike, enabling informed decision-making and leveraging the full potential of the Java ecosystem.

Friday, March 15, 2024

Unlocking the Potential: An In-Depth Oracle Java Networking Overview

Unlocking the Potential: An In-Depth Oracle Java Networking Overview

Oracle Java Networking stands as a pivotal aspect of modern computing infrastructure, empowering seamless communication and data exchange across networks. In this comprehensive overview, we delve into the intricacies of Oracle Java Networking, exploring its significance, components, functionalities, and practical applications.

Understanding Oracle Java Networking


At its core, Oracle Java Networking encompasses a suite of technologies and protocols facilitating network communication within Java applications. Leveraging Java's platform independence, Oracle Java Networking enables developers to create robust, cross-platform networked applications with unparalleled efficiency and reliability.

Components of Oracle Java Networking


1. Java.net Package

The java.net package serves as the cornerstone of Oracle Java Networking, offering a comprehensive set of classes and interfaces for network programming. From establishing connections to handling data streams, this package provides developers with essential tools for building sophisticated networked applications.

2. Socket Programming

Socket programming lies at the heart of Oracle Java Networking, enabling bidirectional communication between client and server applications. Leveraging sockets, developers can create robust networked solutions capable of transmitting data across diverse network topologies.

3. URL Handling

Oracle Java Networking simplifies URL handling through built-in classes like URL and URLConnection, facilitating seamless interaction with web resources. From retrieving data to establishing secure connections, these classes streamline the process of web communication within Java applications.

Functionalities of Oracle Java Networking


1. Network Protocol Support

Oracle Java Networking boasts extensive support for various network protocols, including HTTP, FTP, TCP/IP, and UDP. This versatility empowers developers to integrate diverse network functionalities into their Java applications, catering to a wide range of use cases and scenarios.

2. Secure Communication

With built-in support for SSL/TLS protocols, Oracle Java Networking ensures secure communication over the network. By implementing robust encryption and authentication mechanisms, developers can safeguard sensitive data and protect against potential security threats.

3. Asynchronous I/O Operations

Oracle Java Networking facilitates asynchronous I/O operations through non-blocking socket channels and selectors. This asynchronous model enhances application performance by enabling concurrent network communication without blocking the main execution thread.

Practical Applications of Oracle Java Networking


1. Web Development

Oracle Java Networking plays a pivotal role in web development, enabling the creation of dynamic and interactive web applications. From client-server communication to data retrieval and processing, Java networking capabilities empower developers to build scalable and responsive web solutions.

2. Enterprise Networking

In the realm of enterprise networking, Oracle Java Networking facilitates seamless integration of disparate systems and services. Whether it's implementing communication protocols for distributed computing or orchestrating complex network infrastructures, Java networking empowers organizations to streamline their operations and enhance productivity.

3. Internet of Things (IoT)

With the proliferation of IoT devices, Oracle Java Networking emerges as a vital enabler of connected ecosystems. By leveraging Java's robust networking capabilities, IoT developers can create scalable and interoperable solutions for managing and controlling smart devices over the network.

Conclusion

In conclusion, Oracle Java Networking stands as a cornerstone of modern networked applications, offering a robust platform for seamless communication and data exchange. From its versatile components to its extensive functionalities, Java networking empowers developers to build scalable, secure, and interconnected solutions across diverse domains and industries.

Wednesday, March 13, 2024

Unleashing the Power of Oracle Java User Datagram Protocol (UDP)

Unleashing the Power of Oracle Java User Datagram Protocol (UDP)

In the realm of networking protocols, the User Datagram Protocol (UDP) stands as a stalwart, facilitating swift and efficient data transmission across networks. Within this expansive landscape, Oracle Java harnesses the prowess of UDP to enhance connectivity, streamline communication, and fortify the foundation of networked applications. Let us delve into the intricacies of Oracle Java UDP, uncovering its capabilities, applications, and the myriad benefits it bestows upon developers and users alike.

Understanding Oracle Java and UDP


What is Oracle Java?

Oracle Java, a renowned programming language and computing platform, reigns supreme in the realm of software development. Offering unparalleled versatility, scalability, and performance, Java empowers developers to craft robust, platform-independent applications that transcend boundaries.

The Significance of UDP

User Datagram Protocol (UDP), a core component of networking protocols, operates at the transport layer of the Internet Protocol (IP) suite. Unlike its counterpart, Transmission Control Protocol (TCP), UDP prioritizes speed and efficiency over reliability, making it ideal for applications where real-time data transmission is paramount.

The Evolution of Oracle Java UDP


Origins and Development

Oracle Java UDP has evolved significantly since its inception, undergoing iterative refinements and enhancements to meet the evolving demands of modern networking paradigms. From its nascent stages to its current iteration, Oracle Java UDP has remained at the forefront of innovation, adapting to technological advancements and industry trends.

Key Features and Capabilities

Oracle Java UDP boasts a myriad of features and capabilities, empowering developers to create high-performance, low-latency applications with unparalleled ease. Some notable features include:

  • Low Overhead: Oracle Java UDP minimizes protocol overhead, ensuring swift data transmission and minimal latency.
  • Multicast Support: Leveraging multicast capabilities, Oracle Java UDP facilitates efficient one-to-many communication, enabling real-time collaboration and data dissemination.
  • Asynchronous Communication: With support for asynchronous communication, Oracle Java UDP empowers developers to design responsive and scalable applications that cater to diverse use cases.

Applications and Use Cases


Real-Time Communication

Oracle Java UDP finds widespread application in real-time communication systems, such as voice over IP (VoIP), online gaming, and live streaming platforms. By leveraging the low-latency nature of UDP, these applications deliver seamless, immersive experiences to users worldwide.

Internet of Things (IoT)

In the realm of IoT, where interconnected devices communicate seamlessly to facilitate automation and data exchange, Oracle Java UDP serves as a linchpin, enabling efficient device-to-device communication and sensor data aggregation.

Networked Applications

From peer-to-peer file sharing to distributed computing systems, Oracle Java UDP powers a myriad of networked applications, enabling seamless data exchange and collaboration across disparate nodes.

Benefits of Oracle Java UDP


Performance and Scalability

By prioritizing speed and efficiency, Oracle Java UDP enables developers to build high-performance applications that scale effortlessly to meet the demands of modern networking environments.

Flexibility and Versatility

With its robust feature set and platform-independent nature, Oracle Java UDP empowers developers to create versatile applications that run seamlessly across diverse operating systems and hardware architectures.

Enhanced User Experience

By facilitating real-time communication and low-latency data transmission, Oracle Java UDP enhances the user experience, enabling immersive, responsive applications that captivate and delight users.

Conclusion

In conclusion, Oracle Java UDP stands as a cornerstone of modern networking, empowering developers to craft high-performance, low-latency applications that transcend boundaries and redefine user experiences. With its robust feature set, unparalleled performance, and widespread applicability, Oracle Java UDP continues to shape the landscape of networked applications, ushering in a new era of connectivity and collaboration.

Friday, February 9, 2024

Unleashing the Power of Java ME Embedded

Unleashing the Power of Java ME Embedded

Java ME Embedded, a subset of the Java SE platform tailored for embedded systems, is revolutionizing the way we approach software development for resource-constrained devices. In this comprehensive guide, we delve deep into the capabilities, advantages, and applications of Java ME Embedded, shedding light on why it stands as a formidable force in the realm of embedded programming.

Understanding Java ME Embedded


At its core, Java ME Embedded empowers developers to build robust, scalable applications for embedded devices, ranging from sensors and wearables to industrial machinery and smart appliances. Leveraging the power of Java's object-oriented programming paradigm, Java ME Embedded offers a versatile environment for creating applications that demand efficiency, reliability, and flexibility.

Key Features and Capabilities


1. Compact Footprint

One of the standout features of Java ME Embedded is its ability to operate within a compact footprint, making it ideal for devices with limited memory and processing resources. By optimizing resource utilization, Java ME Embedded ensures that applications can run smoothly even on constrained hardware platforms.

2. Platform Independence

Java ME Embedded embraces the ethos of "write once, run anywhere," allowing developers to write code that can seamlessly run on diverse hardware architectures. This platform independence not only simplifies development but also future-proofs applications against changes in underlying hardware configurations.

3. Built-in Security

Security is paramount in the realm of embedded systems, where vulnerabilities can have far-reaching consequences. Java ME Embedded addresses this concern by integrating robust security mechanisms, including sandboxing, cryptographic libraries, and secure communication protocols, to safeguard both data and device integrity.

4. Extensive Library Support

With a rich repository of libraries and APIs, Java ME Embedded provides developers with a wealth of resources to accelerate development and streamline implementation. Whether it's interfacing with sensors, communicating over networks, or processing data, the comprehensive library support of Java ME Embedded simplifies complex tasks and empowers developers to focus on innovation.

Applications of Java ME Embedded


The versatility of Java ME Embedded lends itself to a myriad of applications across various industries, transforming the landscape of embedded systems development. Some notable applications include:

1. IoT Devices

In the era of the Internet of Things (IoT), Java ME Embedded serves as a cornerstone for building connected devices that form the backbone of smart homes, industrial automation, and intelligent infrastructure. From smart thermostats to industrial sensors, Java ME Embedded enables seamless connectivity and interoperability in the IoT ecosystem.

2. Automotive Systems

The automotive industry relies heavily on embedded systems to power everything from in-car entertainment systems to advanced driver-assistance features. Java ME Embedded offers automotive manufacturers a robust platform for developing software solutions that enhance safety, efficiency, and user experience across the entire vehicle fleet.

3. Healthcare Devices

In healthcare, embedded systems play a crucial role in monitoring patient vital signs, administering medication, and managing medical equipment. Java ME Embedded provides a secure and reliable framework for developing medical devices that adhere to stringent regulatory standards while delivering superior performance and interoperability.

4. Industrial Automation

In industrial settings, Java ME Embedded facilitates the automation of processes, monitoring of equipment, and optimization of operations. By leveraging Java's scalability and portability, industrial manufacturers can deploy embedded solutions that increase productivity, reduce downtime, and enable predictive maintenance.

Conclusion

In conclusion, Java ME Embedded empowers developers to unleash the full potential of embedded systems, offering a robust and versatile platform for building innovative applications across diverse industries. With its compact footprint, platform independence, built-in security, and extensive library support, Java ME Embedded stands as a testament to the power of Java in the realm of embedded programming.

Monday, December 18, 2023

Eyes on the horizon of evolving customer expectations

Eyes on the horizon of evolving customer expectations

Over the next few weeks, I look forward to sharing with you – in a five-part series – our point of view on the future of customer experience. Let’s get started. There is a lot to talk about.

When we raise our eyes to the CX horizon, what do we see?

It’s clear the future of CX is exciting. It’s a place where customers act and react in a blink of an eye. They expect to be part of immersive, digitally native, physically enhanced shared moments; they expect to be remembered, valued, and rewarded for length and steadiness of their on-going relationship with your business. Being a customer now has never been more empowering – or more frustrating. Being a CX professional now – business, or technical – has never been more exciting – or more difficult.

Some very clear expectations and pressures have changed how customers engage, how businesses deliver value, and how enterprise IT teams deliver on CX innovation. That future is certainly promising – and much closer than many may realize.

Let’s take a look.

We, customers, have perpetually evolving expectations.

We all communicate differently. Not just in real-life, also in real-work. As consumers we have long used asynchronous channels socially. As customers we will pay more just for a unified experience anywhere, anytime, all-the-time. And small, continuous gestures mean a lot to our experience of a brand– like the best forward-thinking brands that thank frequent customers with small gifts like extra points or a recognition of loyalty for a long trip or big purchase. Every little engagement matters. They all add up. And accustomed to the convenience of always-on experiences that ‘just work’ across all channels in private life, business professionals now expect the same convenience when engaging with brands whether at work or at play.

We are embracing outcomes over ownership. Subscriptions help us spread costs and payments over time rather than pay upfront, with more predictable finances. Every business today – from retail and consumers goods, to industrial manufacturers – is changing how they offer new digital experiences for existing products and services. The success of the sharing economy and the ‘-as a Service’ of manufactured goods has changed expectations for how we consume at home and at work: Tacos (“Taco Bell brings back the $10 Taco Subscription”) to how builders pay for the use of heavy machinery like pay-by-the-use construction cranes. Subscription-based products and services offer countless advantages with mutual benefits for both the customer and the business. For customers, subscription business models grant the right to access products, services, or experiences in a recurring fashion and meet our desire to become asset-light. For businesses, subscription models provide new opportunities for upselling and cross-selling to increase share of wallet within the existing customer base.

We expect privacy. We certainly will pay more – engage more – with personalized, convenient experiences and services. But there is an important caveat. We expect the utmost discretion for the privilege of accessing any part of our digital identity. When used for good, sharing our data can earn us quick compensation for a flight delay, or empathetic outreach from an insurance company when we are having trouble resolving a problem. When our data is not shielded, businesses risk losing customer trust forever.

And we’re not making it easy on businesses. Because it’s not enough to just use our data for customer analysis or targeting. Today we expect brands to proactively lead us along the best journey for me (me, me, me, me). Recommendations, next best offers, next best purchases, and any other predictive engagements must directly benefit me like as if I were your only and most important customer. Use my data to personalize the experience – but also preempt problems or add value throughout my journey.

We – as customers – are clearly forcing a lot of change and raising the bar every day with what we expect from customer experience delivery. The bar for businesses has never been higher. And so, in my second blog in this series, I look forward to sharing with you, my thoughts on the way businesses need to deliver value and constant customer experience innovation.

Source: oracle.com

Wednesday, October 25, 2023

Java vs. Oracle: Deciphering the Battle of Titans

Java, Oracle, Oracle Java, Oracle Java Career, Oracle Java Skills, Oracle Java Jobs, Oracle Java Prep, Oracle Java Preparation, Oracle Java Tutorial and Materials

In the ever-evolving world of technology, the comparison between Java and Oracle is a hot topic. Both are powerhouse solutions, each with its own set of unique strengths and applications. In this comprehensive guide, we'll dive deep into the realm of Java and Oracle, dissecting their capabilities, use cases, and advantages to help you make an informed decision.

The Java Odyssey


Java is an open-source, versatile programming language that has left an indelible mark on the tech world. Created by Sun Microsystems (now owned by Oracle Corporation), Java is celebrated for its platform independence. This means you can write code once and run it on multiple platforms without modification, making it a preferred choice for developers.

Key Advantages of Java


1. Platform Independence: As previously mentioned, this is Java's crowning glory. It's compatible with various operating systems, including Windows, macOS, and Linux, which greatly eases the development process.

2. Robust and Secure: Java's strong memory management, automatic garbage collection, and extensive security features make it a dependable choice for mission-critical applications.

3. Vast Community Support: With a massive developer community, Java boasts a wealth of resources, libraries, and frameworks. If you have a question, someone out there has an answer.

4. Scalability: Whether you're working on a small project or a colossal enterprise-level application, Java can handle it all. Its scalability is second to none.

Common Use Cases for Java


◉ Web Development: Popular web frameworks like Spring and JavaServer Faces (JSF) make Java an excellent choice for building web applications.

◉ Android App Development: Java is the official language for Android app development, making it indispensable for mobile developers.

◉ Big Data Processing: Hadoop, an open-source big data framework, is built on Java, demonstrating its prowess in handling vast amounts of data.

The Oracle Enigma


Oracle, on the other hand, is renowned for its prowess in the database management domain. It's a juggernaut in the world of relational database systems. Oracle Corporation, the brains behind this technology, has created a suite of tools and technologies that cater to the demands of businesses and enterprises worldwide.

Key Advantages of Oracle


1. High Performance: Oracle databases are known for their lightning-fast performance. They can efficiently manage large datasets, making them ideal for businesses with substantial data needs.

2. Data Security: Oracle places a significant emphasis on data security. It offers various features to protect your data from unauthorized access or malicious attacks.

3. Scalability: Just like Java, Oracle databases are highly scalable, accommodating the growth of your business without a hitch.

4. Comprehensive Ecosystem: Oracle provides a wide range of products and services, including cloud solutions, making it a one-stop-shop for all your database and data management needs.

Common Use Cases for Oracle


◉ Enterprise Database Management: Oracle databases are the go-to choice for businesses and organizations with extensive data management requirements.

◉ Data Warehousing: The ability to handle and analyze massive datasets makes Oracle the prime choice for data warehousing.

◉ Cloud Solutions: Oracle's cloud services offer scalable, secure, and high-performance options for businesses migrating to the cloud.

The Face-Off


Now that we've examined the individual strengths of Java and Oracle, it's time to pit them against each other.

Performance

In the performance arena, Oracle holds a slight edge due to its dedicated focus on database management. It's finely tuned for handling data, providing blazing-fast data retrieval and processing. However, Java can be optimized for various applications, so performance can vary based on the specific use case.

Versatility

Java takes the lead in versatility. Its ability to function across diverse platforms and applications is unmatched. Oracle, while versatile in its own right, excels primarily in database management.

Security

Both Java and Oracle place a strong emphasis on security, but Oracle's database security features give it a slight advantage in this department.

Scalability

Here, it's a tie. Both Java and Oracle are highly scalable, ensuring they can grow with your business.

Which One Should You Choose?


The choice between Java and Oracle ultimately depends on your specific needs and objectives. If you're developing a web application, mobile app, or working in a diverse tech environment, Java is the natural choice. On the other hand, if your primary concern is managing and securing data, then Oracle should be your top pick.

It's essential to evaluate your project's requirements and consult with experts to make an informed decision. While you can't go wrong with either choice, selecting the one that aligns best with your goals is crucial.

In conclusion, the battle of Java vs. Oracle is not about one being better than the other; it's about which one suits your requirements. Each has its unique strengths, and both are integral components of the ever-expanding tech landscape.

Monday, October 23, 2023

Unveiling Java 21: The Future of Programming

Unveiling Java 21, Core Java, Java Prep, Java Preparation, Java Guides, Oracle Java Certification

In the dynamic realm of programming, the emergence of new versions and technologies is a frequent occurrence, making it essential for software developers and enthusiasts to stay updated. Java, a stalwart in the programming world, has recently unveiled its latest iteration - Java 21. This article delves into the exciting features and improvements that Java 21 brings to the table, equipping you with the knowledge to stay at the forefront of the programming landscape.

Understanding Java 21


Java, known for its versatility, portability, and reliability, has undergone a significant transformation in its latest release. Java 21 promises to further enhance these characteristics while introducing various novel elements to make it an even more powerful tool in the hands of developers.

1. Enhanced Performance

Java 21 is designed to be faster and more efficient than its predecessors. With optimized execution, this version reduces startup times and accelerates the execution of code. The improved performance ensures that Java remains a top choice for both small-scale applications and large-scale enterprise systems.

2. Records and Pattern Matching

One of the standout features of Java 21 is the introduction of Records and Pattern Matching. Records simplify the creation of immutable classes, streamlining the process of defining data-centric classes. Pattern Matching, on the other hand, enhances the readability and expressiveness of your code by allowing concise conditional statements.

3. Project Loom

Java 21 brings Project Loom to the forefront, a significant development that aims to simplify concurrency. With Loom, you can write concurrent code that is more readable and maintainable, making it easier to work with threads and asynchronous programming.

4. Foreign Function & Memory API

To keep pace with modern programming trends, Java 21 introduces the Foreign Function & Memory API, allowing seamless interaction with native code and memory. This feature empowers developers to access and utilize external libraries with ease.

5. Pattern Matching for instanceof

Pattern Matching for instanceof is another exciting addition. It simplifies type checking and casting by introducing a concise and intuitive syntax. This enhancement fosters clean and robust code practices.

6. Deprecation and Removal of Older Features

Java 21 takes a step forward by deprecating and removing outdated features. This ensures that the language remains concise and relevant, and it encourages developers to embrace modern and more efficient programming practices.

How Can Java 21 Benefit You?


With Java 21, developers, both seasoned and newcomers, can benefit immensely. Here are some of the advantages you can expect:

1. Improved Productivity

The enhanced features in Java 21 lead to increased productivity. Writing code becomes more intuitive and efficient, reducing the time and effort required to develop software.

2. Enhanced Code Quality

Java 21 encourages best practices and clean coding. The introduction of Records, Pattern Matching, and other features helps developers write more robust and less error-prone code.

3. Competitive Edge

Staying updated with the latest programming languages and features is essential in a rapidly evolving field. By mastering Java 21, you gain a competitive edge in the job market and software development landscape.

Transitioning to Java 21


If you're already using Java in your projects, transitioning to Java 21 is a logical step. However, it's essential to understand that some older features may be deprecated, and you may need to refactor your code accordingly. The effort is worthwhile, as the benefits of Java 21 are substantial.

For newcomers to Java, Java 21 is a fantastic place to start. You'll be learning the latest version, which means you'll be equipped with the most up-to-date skills in the Java ecosystem.

Friday, October 20, 2023

Unleashing the Power of Oracle Java

Unleashing the Power of Oracle Java: A Comprehensive Guide

In the ever-evolving world of technology, Oracle Java stands as an indispensable platform that has shaped the way we develop and run applications. In this comprehensive guide, we delve deep into the world of Oracle Java, exploring its significance, applications, and why it remains a pivotal player in the realm of programming languages and platforms.

The Genesis of Oracle Java


Oracle Java, often simply referred to as Java, is a robust, versatile, and object-oriented programming language and platform that was first introduced by Sun Microsystems in 1995. Since then, it has undergone significant advancements under Oracle Corporation, solidifying its position as a preferred choice for developers across the globe.

The Versatility of Java


Java's Role in Web Development

One of Java's primary applications is in web development. Its ability to create dynamic, interactive, and secure web applications has made it a go-to choice for web developers. Java's compatibility with a wide array of web frameworks and libraries makes it a versatile language for crafting feature-rich websites and web applications.

Enterprise-Level Solutions

Java is renowned for its capability to handle large-scale enterprise applications. Its scalability and reliability are second to none, making it an ideal choice for businesses seeking to develop robust, secure, and efficient software solutions.

Android App Development

If you're a fan of Android apps, you can thank Java for a significant part of your app experience. Java is the primary language used for Android app development, ensuring a vast array of high-quality apps available for Android users.

Key Features and Advantages


Platform Independence

One of Java's standout features is its "Write Once, Run Anywhere" capability. This means that once you've written Java code, it can run on any platform that supports Java, making it a valuable tool for developers aiming for cross-platform compatibility.

Strong Security

Security is paramount in today's digital landscape, and Java takes this aspect very seriously. Its robust security features, such as bytecode verification and the ability to run in a sandbox, make it a trusted choice for applications requiring top-notch security.

Rich Ecosystem

Java boasts a rich ecosystem of libraries, frameworks, and tools that simplify and expedite the development process. From Spring Framework to Hibernate, Java developers have access to a vast array of resources to enhance productivity.

The Java Community


The Java community is a vibrant, dynamic, and globally distributed network of developers and enthusiasts. With a vast pool of knowledge and resources, it's no wonder that Java continues to thrive and adapt to the ever-changing demands of the tech world.

Staying Relevant: Java's Future


As technology advances at an unprecedented pace, Java continues to evolve to meet new challenges and opportunities. Recent Java versions have introduced features like Records, Pattern Matching, and Project Loom, further enhancing its capabilities and performance.

Conclusion

In a technology-driven world, the power of Oracle Java cannot be overstated. From web development to enterprise-level solutions, Java remains at the forefront of innovation. Its platform independence, security features, and rich ecosystem make it a compelling choice for developers worldwide.

Monday, August 28, 2023

Going inside Java 21’s rich, upcoming goodness

Final features, continuing previews, and brand-new treats—with video links


Are you ready for all the new technology in Java 21? This article will take you on a tour of many of the changes, small and large, covering final JEPs, a progressing preview, and something entirely new for the platform.

Final features


Virtual threads. Let’s start with the big one: After two rounds of preview with barely any changes, virtual threads are final in Java 21. Now web frameworks are off to the races because they need to let you easily configure using virtual threads instead of platform threads to handle requests.

Oracle Java Career, Oracle Java Skills, Oracle Java Jobs, Oracle Java Preparation, Oracle Java Tutorial and Materials, Oracle Java Certification, Oracle Java Learning, Oracle Java Guides

Configuring virtual threads has the potential to let your app handle way more concurrent connections than before. But keep in mind that virtual threads aren’t performance pixie dust, so keep expectations realistic. Then again, if you don’t see the results you’re hoping for, there may be some easy code changes you can do that get you there. Watch episode 23 of the Inside Java Newscast for more on that and some virtual thread guidelines.

Sequenced collections. Many collections in Java have a stable iteration order (all lists and some sets, for example) but don’t necessarily allow indexed access to them (all lists do, but sets usually don’t). Java 21 steps up its collections game and introduces a set of new interfaces that capture this concept and offer related functionality.

At the core of these new interfaces is SequencedCollection, which extends Collection and is ultimately implemented by all lists, some sets, and a few other data structures. It offers the addFirst, addLast, getFirst, getLast, removeFirst, and removeLast methods, which do what you’d expect.

// getting first and last elements from a list
// (sequenced by order of addition)

var letters = List.of("c", "b", "a");
"c".equals(letters.getFirst());
"a".equals(letters.getLast());

// same but from a sorted set
// (sequenced by natural ordering)

var letterSet = new TreeSet<>(letters);
"a".equals(letters.getFirst());
"c".equals(letters.getLast());

There’s also a new method called reversed that returns a SequencedCollection that is a view on the underlying collection but in reverse order, which makes it super easy to iterate or stream over the collection.

var letters = new ArrayList<>(List.of("a", "b", "c"));
var reversedLetters = letters.reversed();

letters.addLast("d");
reversedLetters.forEach(System.out::print);
// ~> dcba

reversedLetters.addFirst("e");
letters.forEach(System.out::print);
// ~> abcde

If you want to learn more about that, the companion interfaces SequencedSet and SequencedMap, and a few odds and ends, check out episode 25 of the Inside Java Newscast.

Generational low-pause garbage collection. Garbage collection is also taking big steps forward. The Z Garbage Collector (ZGC) has a strong focus on ultralow pause times, which can lead to a higher memory footprint or higher CPU usage than other garbage collectors. Starting with Java 21, both of these metrics will be improved on many workloads when ZGC becomes generational, meaning it will maintain separate generations for young objects, which tend to die young, and old objects, which tend to be around for some time.

Preliminary benchmarks show very promising results: In a probably not-representative case, Cassandra 4 showed

◉ Four times the throughput on generational ZGC compared to ZGC with a fixed heap
◉ A quarter of the heap size on generational ZGC compared to ZGC with stable throughput

If you want to give generational ZGC a try on your workload, download a Java 21 early access build and launch it with -XX:+UseZGC -XX:+ZGenerational

Pattern matching. To effectively use pattern matching, you need three things.

◉ A capable switch that allows the application of patterns
◉ The ability to enforce limited inheritance so the switch can check exhaustiveness
◉ An easy way to aggregate and deconstruct data

var shape = loadShape();
var area = switch(shape) {
    case Circle(var r) -> r * r * Math.PI;
    case Square(var l) -> l * l;
    // no default needed
}

sealed interface Shape permits Circle, Square { }
record Circle(double radius) { }
record Square(double length) { }

There are other features that come in really handy (and they are being worked on and one even previews in Java 21—more on that later), but these are the basics, and Java 21 finalizes the last two pieces: pattern matching for switch and record patterns. With these features, you can use this powerful idiom in your projects—be it in a small or large way—if you use a functional or data-oriented approach. To see how these features play together to achieve that, check out episode 29 of the Inside Java Newscast.

Key encapsulation mechanism API. Do you know the Diffie-Hellman key exchange encapsulation (DHKEM) algorithm? If you don’t, you should definitely look into it. On the face of it, the algorithm sounds impossible. It lets two parties compute an encryption key, which is a number, while preventing an observer, who sees every exchanged message, from feasibly redoing the computation, ensuring that the key is a secret that only the two parties know. As you can imagine, that’s very helpful when you need to exchange encrypted information between parties that have no prior knowledge of each other. Hence, the DHKEM algorithm is widely used, for example, to provide forward secrecy in TLS.

Like all key encapsulation mechanisms, DHKEM is a building block of hybrid public key encryption (HPKE) and will be an important tool for defending against quantum attacks. Starting with Java 21, Java has an API to represent key encapsulation mechanisms in a natural way.

Now you’re probably wondering what the API looks like. It’s all described in episode 54 of the Inside Java Newscast with Ana-Maria Mihalceanu.

New view command for JDK Flight Recorder. The JDK Flight Recorder is an amazing piece of tech, and it’s getting better with every JDK release. JDK 21 added the view command, which displays aggregated event data on the terminal. This way, you can view information about an application without the need to dump a recording file or open up JDK Mission Control. Billy Korando explains all in episode 53 of the Inside Java Newscast.

API improvements

Java 21 comes with a number of small additions to existing APIs. Let’s quickly go over them, so you’re aware of where the JDK can do your work for you.

Emoji. The Character class gained a few static checks that let you identify emojis; first and foremost is isEmoji.

var codePoint = Character.codePointAt("😃", 0);
var isEmoji = Character.isEmoji(codePoint);
// prints "😃 is an emoji: true"
System.out.println("😃 is an emoji: " + isEmoji);

Math. The Math class got static clamp methods that take a value, a minimum, and a maximum and return a value that is forced into the [min, max] interval. There are four overloads for the four numerical primitives.

double number = 83.32;
double clamped = Math.clamp(number, 0.0, 42.0);
// prints "42.0"
System.out.println(clamped);

Repeat methods. StringBuilder and StringBuffer gained repeat methods, which allow you to add a character sequence or a code point multiple times to a string that is being built.

var builder = new StringBuilder();
builder.append("Hello");
builder.append(", ");
builder.repeat("World", 3);
builder.append("!");
// prints "Hello, WorldWorldWorld!"
System.out.println(builder);

String. String’s indexOf methods gain overloads that take a maxIndex, as follows:

var hello = "Hello, World";
var earlyCommaIndex = hello.indexOf(",", 0, 3);
// prints "-1"
System.out.println(earlyCommaIndex);

Also, string’s new splitWithDelimiters method behaves like the split method but includes the delimiters in the returned array. The same splitWithDelimiters method was added to Pattern, by the way.

var hello = "Hello; World";
var semiColonSplit = hello.splitWithDelimiters(";", 0);
//prints [Hello, ;,  World]
System.out.println(Arrays.toString(semiColonSplit));

List shuffles. Need to shuffle a List in place with a RandomGenerator? Then that’s your reason to update to Java 21! Once you do, you can pass the list and a RandomGenerator to Collections::shuffle, and it’ll shuffle the list.

var words = new ArrayList<>(List.of("Hello", "new", "Collections", "shuffle", "method"));
var randomizer = RandomGenerator.getDefault();
// using this API makes way more sense when you’re not using the default generator
Collections.shuffle(words, randomizer);
// prints the words above but with a 99.17% chance of a different order
System.out.println(words);

HttpClient. An HttpClient can now be instructed to close, to shut down, or to await termination, but those are best-effort implementations that can have adverse interactions with open request or response body streams.

var httpClient = HttpClient.newHttpClient();
// use the client
httpClient.close();

// or call shutdown and awaitTermination
// yourself for more control:
var httpClient = HttpClient.newHttpClient();
// use the client
httpClient.shutdown();
httpClient.awaitTermination(Duration.ofMinutes(1));

// it also implements AutoCloseable
try (var httpClient = HttpClient.newHttpClient()) {
    // use the client
}

Locales. The Locale.availableLocales() method returns a stream of all available locales.

var locales = Locale
    .availableLocales()
    .map(Locale::toString)
    .filter(locale -> !locale.isBlank())
    .sorted()
    .collect(Collectors.joining(", "));
// prints af, af_NA, af_ZA, af_ZA_#Latn, agq, ...
System.out.println(locales);

Case-folded tags. And because you’ve all asked for case-folded IETF BCP 47 language tags (don’t pretend that you didn’t), Locale gained the caseFoldLanguageTag method.

var lang = Locale.caseFoldLanguageTag("fi-fi");
// prints "fi-FI" (note the RFC5646-correct case)
System.out.println(lang);

Continued evolution

Now it’s time to transition from finalized features to previews, incubators, and experiments. To use a preview feature, you need to add the command-line flag --enable-preview to javac and java, and you also need to specify the Java version for javac, preferably with --release 21.

Structured concurrency. Once you get abundant virtual threads and start creating one virtual thread for every little concurrent task you have, an interesting opportunity arises: You can treat threads that you created for a set of tasks as if they are executing a single unit of work, and you can see them as children of the thread that created them.

An API that capitalizes on that would streamline error handling and cancellation, improve reliability, and enhance observability. And it would make it easy and helpful to start and end that single unit of work in the same scope, defining a unique entry and exit point for handling concurrent code. It would do for concurrency what structured programming did for control flow: add much-needed structure.

Lucky us, because such an API exists! It’s called the Structured Concurrency API.

// create task scope with desired
// error handling strategy
// (custom strategies are possible)
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {

    // fork subtasks
    Subtask<String> user = scope.fork(() -> findUser());
    Subtask<Integer> order = scope.fork(() -> fetchOrder());

    scope
        // wait for both subtasks
        .join()
        // propagate potential errors
        .throwIfFailed();

    // both subtasks have succeeded
    // ~> compose their results
    // (these calls are nonblocking)
    return new Response(user.get(), order.get());
} // task scope gets shut down

The Structured Concurrency API was incubating in Java 20 and is upgraded to a preview in Java 21. Beyond moving to a proper package, namely java.util.concurrent, the only change has been that StructuredTaskScope’s fork method now returns the new type Subtask. In Java 20, the fork method returned a Future, but that offered degrees of freedom (such as calling the blocking getmethod) that are counterproductive in structured concurrency and was overall too evocative of asynchronous programming, which is exactly what structured concurrency isn’t.

José Paumard has a video tutorial on all this; to see it, check out episode 13 of JEP Café.

Scoped values. The ThreadLocal API is used to store thread-specific information, usually in static final fields, which can then be queried from anywhere those variables are visible. That’s useful, for example, when a container, such as a web server, needs to make information accessible to other parts of its code that it doesn’t call directly. It’s also useful when it doesn’t want to pass that information on explicitly, either for convenience or integrity reasons.

class Server {

    // Principal needs to be visible to other code...
    final static ThreadLocal<Principal> PRINCIPAL = new ThreadLocal<>();

    void serve(Request request, Response response) {
        var level = request.isAuthorized() ? ADMIN : GUEST;
        var principal = new Principal(level);
        PRINCIPAL.set(principal);
        // ... but not the application
        Application.handle(request, response);
    }

}

However, ThreadLocal has a few shortcomings:

◉ Anyone with access to the ThreadLocal field can read its value and also set a new one.

◉ Values stored in ThreadLocal can be inherited from one thread to another. To prevent the other threads from reading an updated value (which the API should explicitly prevent; it’s thread local, after all), the inheriting thread must create copies. These drive up memory use, especially when there are many threads—you know, the whole “millions of virtual threads” thing.

◉ Once set, values must be explicitly removed (using the ThreadLocal::remove method) or they will leak beyond their intended use and continue to occupy memory.

To solve these problems, Java 20 incubated and Java 21 previews the Scoped Values API, which works by binding a value to the ScopedValue instance and passing the code that is allowed to read that value as a lambda—that’s the scope.

class Server {

    final static ScopedValue<Principal> PRINCIPAL = new ScopedValue<>();

    void serve(Request request, Response response) {
        var level = request.isAdmin() ? ADMIN : GUEST;
        var principal = new Principal(level);
        ScopedValue
            // binds principal to PRINCIPAL, but...
            .where(PRINCIPAL, principal)
            // ... only in the scope that is defined by this lambda
            .run(() -> Application.handle(request, response));
    }

}

The Scoped Values API addresses the following ThreadLocal issues:

◉ Within the scope, the bound value is immutable.
◉ Accordingly, no copies need to be created when inheriting, which significantly improves scalability.
◉ As the name implies, a scoped value is visible only within the defined scope; after that, the value is automatically removed, so it cannot accidentally leak.

To see scoped values in practice, watch episode 16 of JEP Café. In it, José Paumard talks about the early version of the API as it was in Java 20 and about what changes in Java 21; besides moving to java.lang, the changes mean the scope (the lambda) can now be a Callable, Runnable, and Supplier.

Vector API. The Vector API is in its sixth incubation and still waiting for Project Valhalla. There’s nothing new to see here, so please move on unless you want to see vectors in action. In that case, check out José Paumard’s episode 18 of JEP Café.

Foreign Function and Memory API. By efficiently invoking code outside the JVM (foreign functions) and by safely accessing memory not managed by the JVM (foreign memory), the Foreign Function and Memory API enables Java programs to call native libraries and process native data without the brittleness and danger of the Java Native Interface (JNI).

One of the main drivers of this API is to provide safe and timely deallocation in a programming language whose main staple is automatic deallocation (thanks, garbage collector).

Finding the right primitive to express this capability in a way that is harmonious with the rest of the Java programming model triggered a round of API changes in Java 20 and again in Java 21, which is why the API will take another round of previewing.

// 1. find foreign function on the C library path
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle radixsort = linker.downcallHandle(stdlib.find("radixsort"), ...);

// 2. allocate on-heap memory to store four strings
String[] words = { "mouse", "cat", "dog", "car" };

// 3. use try-with-resources to manage the lifetime of off-heap memory
try (Arena offHeap = Arena.ofConfined()) {
    // 4. allocate a region of off-heap memory to store four pointers
    MemorySegment pointers = offHeap
        .allocateArray(ValueLayout.ADDRESS, words.length);
    // 5. copy the strings from on-heap to off-heap
    for (int i = 0; i < words.length; i++) {
        MemorySegment cString = offHeap.allocateUtf8String(words[i]);
        pointers.setAtIndex(ValueLayout.ADDRESS, i, cString);
    }

    // 6. sort the off-heap data by calling the foreign function
    radixsort.invoke(pointers, words.length, MemorySegment.NULL, '\0');

    // 7. copy the (reordered) strings from off-heap to on-heap
    for (int i = 0; i < words.length; i++) {
        MemorySegment cString = pointers.getAtIndex(ValueLayout.ADDRESS, i);
        words[i] = cString.getUtf8String(0);
    }

// 8. all off-heap memory is deallocated at the end of the try-with-resources block
}

On that note, the quality of feedback during the preview phase from projects adopting the API has been excellent and very important for its evolution. If you want to help move Java forward, the easiest way to do that is to experiment with preview features and report back to the respective mailing lists.

Another addition in Java 21 has been the so-called fallback linker, which offers a way for platforms to be compliant with Java SE without too much work by using libffi instead of fully implementing the Linker API.

Goodbye 32-bit Windows port. Microsoft Windows 10 was the last 32-bit version of Windows, and it reaches the end of its lifecycle in October 2025. As no surprise, the Java port for 32-bit Windows isn’t heavily maintained anymore. For example, its implementation of virtual threads isn’t virtual at all—the threads fall back to platform threads. So, I guess it was to be expected that the port got deprecated for removal, which Java 21 does.

Brand-new previews

In Java 21 there are three brand-new preview features that I just can’t skip—and I love how diverse they are! They span from improving a Java workhorse to refining a programming paradigm to changing how beginners learn the language.

Unnamed classes and instance main methods. Java 21 allows for much simpler entry points into a Java program. The main method no longer needs to be public or static, nor does it need the args array. And the whole surrounding class becomes optional, too, making void main the smallest possible Java program.

// content of file Hello.java
void main() {
    System.out.println("Hello, World!");
}

You can watch me demonstrate this in episode 49 of the Inside Java Newscast. Let me briefly clarify two points that I didn’t explain very well in that video.

◉ This is a preview feature, so if you use it in a single source–file program, where it clearly shines, you need to add --enable-preview --source 21 to the java command as follows:

java --enable-preview --source 21 Hello.java

◉ There are plans to shorten System.out.println to just println and to also offer a more succinct way to read from the terminal, but neither of those are part of Java 21.

Unnamed variables and patterns. Unused variables are annoying but bearable. Unused patterns during deconstruction, on the other hand, are really cumbersome and clutter code because they make you want to deconstruct less.

String pageName = switch (page) {
    case ErrorPage(var url, var ex)
        -> "💥 ERROR: " + url.getHost();
    case ExternalPage(var url, var content)
        -> "💤 EXTERNAL: " + url.getHost();
    case GitHubIssuePage(var url, var content, var links, int issueNumber)
        -> "🐈 ISSUE #" + issueNumber;
    case GitHubPrPage(var url, var content, var links, int prNumber)
        -> "🐙 PR #" + prNumber;
};

Therefore, it’s really good that Java 21 turns the underscore into a special variable and pattern, which effectively says, “I won’t be used, and you can have as many of me as you want in the same scope.”

String pageName = switch (page) {
    case ErrorPage(var url, _)
        -> "💥 ERROR: " + url.getHost();
    case ExternalPage(var url, _)
        -> "💤 EXTERNAL: " + url.getHost();
    case GitHubIssuePage(_, _, _, int issueNumber)
        -> "🐈 ISSUE #" + issueNumber;
    case GitHubPrPage(_, _, _, int prNumber)
        -> "🐙 PR #" + prNumber;
};

The change makes code more clearly readable and reduces IDE and compiler warnings. Best of all, though, it makes switching over sealed types more maintainable by allowing you to easily combine default handling of different types into a single branch while avoiding an outright default branch.

String pageEmoji = switch (page) {
    case GitHubIssuePage _ -> "🐈";
    case GitHubPrPage _ -> "🐙";
    // explicitly list remaining types to avoid default
    // branch (only possible with unnamed patterns)
    case ErrorPage _, ExternalPage _ -> "n.a.";
};

If you want to better understand why that’s important and how exactly unnamed variables and patterns work, watch episode 46 of the Inside Java Newscast.

String templates. The practice of embedding variables or simple expressions into strings isn’t popular. One reason is that it’s a bit cumbersome and the code is not perfectly readable. But more importantly, if the embedded content comes from the user, there’s the risk of injection attacks. And generally, unless you’re creating text for humans to read, there’s probably syntax and escaping to consider.

// a cumbersome and dangerous example
String property = "last_name";
String value = "Doe";

String query = "SELECT * FROM Person p WHERE p."
    + property + " = '" + value + "'";

String templates solve those problems. They make it easy to embed expressions in string literals or text blocks by encasing them between an opening backslash followed by an opening curly brace and a closing curly brace. They also enforce processing of such string templates by domain-specific string processors.

Such processors receive the string portions and the variables separately and return instances of any type.

The obvious processor simply concatenates and returns a String, but there are other possibilities out there. A SQL processor could validate and parse a statement’s syntax and return a java.sql.Statement, and a JSON processor could return a JsonNode.

// a safe and readable example
String property = "last_name";
String value = "Doe";

Statement query = SQL."""
    SELECT * FROM Person p
    WHERE p.\{property} = '\{value}'
    """;

If you want to dig deeper, check out episode 47 of the Inside Java Newscast by Ana-Maria Mihalceanu.

Source: oracle.com