eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Introduction

In this tutorial, we’ll explore the problem of finding an array’s middle element(s). An array is a data structure that stores data elements of the same type.

The elements of the array are stored in a contiguous fashion in memory and are associated with an index. The array has a fixed length.

2. Problem Statement

Given an array of n elements, we are supposed to return a new array containing the array’s middle element(s). In case the input array is of odd length, there is one middle element for the array. On the other hand, if the input array is of even length, there are two middle elements of the array. 

The output of our code should return an array of either length 1 or 2, depending on the input array. 

Let’s see some examples:

  • Given an input array of 5 elements: [1, 2, 3, 4, 5], the output is [3]. As the array’s length is 5, which is an odd number, we can say that a single middle element exists, in our case 3. 
  • Given an input array of 6 elements: [1, 2, 3, 4, 5, 6], the output is [3, 4]. The array’s length in this case is 6, which is even. Here, both 3 and 4 are the middle elements of the array. 

We should also consider a few edge cases for our problem. For an empty input array, there is no middle element, and hence an empty array is the correct output. The array itself is the output for arrays of lengths 1 and 2. 

3. Middle Element(s) Using Array Operations

An array’s length tells us the number of elements it contains. An array of length n will contain n number of elements in it. The elements can be accessed with a 0-based index. 

3.1. Middle Element of Arrays of Odd Length

Given an array of length n, where n is an odd number, we can say that the array’s first index is always 0, and the last index of the array is n-1. An array of length 99 has indices running from 0 through 98, with index 49 being the middle index. 

We know that the middle point between two values, a and b, is always (a + b) / 2. In our case, considering a = 0 and b = n = 98, we can find the middle index to be (0 + 99) / 2 = 49. Hence, accessing the n/2 element will give us our desired output:

int[] middleOfArray(int[] array) {
    int n = array.length;
    int mid = n / 2;
    return new int[] { array[mid] };
}

It is important to note that n is always an integer as it tells us about the array’s length, and length cannot be fractional. Hence, when we perform n/2, Java will perform an Integer division and will discard the decimal part. So, in our previous example of 99 elements, the middle element will be 99/2 = 49 and not 49.5 or 50. 

3.2. Middle Elements of Arrays of Even Length

Now that we know how to find the middle element of an odd-length array, let’s extend the solution to arrays of even length. 

There is no defined single middle element of an array of even length. An array of length 100 with elements starting from index 0 will have its middle elements at index 49 and 50. Hence, the middle elements of an array of length n, where n is even, are the elements at index (n/2)-1 and n/2As our output depends on the length of the input array, let’s combine them into a single method: 

int[] middleOfArray(int[] array) {
    if (ObjectUtils.isEmpty(array) || array.length < 3) {
        return array;
} int n = array.length; int mid = n / 2; if (n % 2 == 0) { int mid2 = mid - 1; return new int[] { array[mid2], array[mid] }; } else { return new int[] { array[mid] }; } }

Let’s also add a small test to verify that our solution works for all types of arrays: 

int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
    array[i] = i + 1;
}
int[] expectedMidArray = { 50, 51 };
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array));

int[] expectedMidArrayForOddLength = { 50 };
Assert.assertArrayEquals(expectedMidArrayForOddLength, middleOfArray.middleOfArray(Arrays.copyOfRange(array, 0, 99)));

3.3. Middle Element of an Array Between Two Points

In our previous sections, we considered the entire length of the array to be our input, and we calculated the middle of the entire array. A need to calculate the middle element(s) of a portion of the array or a subset given by a start and an end index might arise.

We cannot use the value of n, the length of the array to calculate the middle point anymore. Instead of substituting start = 0 and end = n as we did before, we can use the provided values as is and find the middle point: middle = (start + end) / 2.

int[] middleOfArrayWithStartEnd(int[] array, int start, int end) {
    int mid = (start + end) / 2;
    int n = end - start;
    if (n % 2 == 0) {
        int mid2 = mid - 1;
        return new int[] { array[mid2], array[mid] };
    } else {
        return new int[] { array[mid] };
    }
}

However, this approach has a major drawback. 

Consider that we are dealing with an array with a very large size in the order of Integer.MAX_VALUE. The value Integer.MAX_VALUE is 2147483647. We are required to find the middle element of the array between indices 100 and 2147483647

So in our example, start = 100 and end = Integer.MAX_VALUE. When we apply the formula to find the midpoint, start + end is 4294966747. This value is greater than the Integer.MAX_VALUE and thereby leads to overflow. When we run this in Java, we get -2147483549, which confirms the overflow. 

The fix for this is rather simple. We start by finding the difference between the two values, start and end, and then add (end – start) / 2 to start. So, mid = start + (end – start) / 2This always saves us from overflow:

int[] middleOfArrayWithStartEnd(int[] array, int start, int end) {
    int mid = start + (end - start) / 2;
    int n = end - start;
    if (n % 2 == 0) {
        int mid2 = mid - 1;
        return new int[] { array[mid2], array[mid] };
    } else {
        return new int[] { array[mid] };
    }
}

3.4. Performance of Array Operations to Find the Middle Elements

We know that accessing an element in an array is an O(1) operation. As array elements are placed in contiguous blocks in memory, jumping to a specific index is a constant time operation. Hence, we can say that all the above operations are constant time O(1) operations.

4. Middle Element(s) Using Bitwise Operations

We can use Bitwise operations as an alternative to find the middle elements of an array. Bitwise operations are operations which work on binary digits(bits) of input values. There are many categories of bitwise operators such as Bitwise Logical Operators and Bitwise Shift Operators. 

Here we’ll use a specific type of shift operator called the unsigned right shift operator, i.e. >>>. 

An unsigned right shift operator, as the name suggests shifts all the bits of the input value to the right and the newly created empty spaces are filled with 0. This helps in asserting that the output will always be positive. 

Unsigned shift operators are popularly used to divide a number by a power of 2. So, a >>> n is equivalent to a / (2 ^ n). We use this fact to find the middle element(s) between start and end:

int[] middleOfArrayWithStartEndBitwise(int[] array, int start, int end) {
    int mid = (start + end) >>> 1;
    int n = end - start;
    if (n % 2 == 0) {
        int mid2 = mid - 1;
        return new int[] { array[mid2], array[mid] };
    } else {
        return new int[] { array[mid] };
    }
}

Bitwise operations such as these are faster as they are implemented at a lower level in the hardware, and modern CPUs can take advantage of it. 

5. Median of an Array

In our discussions, we didn’t talk about the nature of elements or their order. A special case arises if the elements in the array are all numerical and sorted in nature. 

The middle element of a sorted data set is called the median value of the dataset and is of great importance in mathematics and statistics. The Median value is a measure of the central tendency of any data set and provides insights into what the typical value of the dataset could be.

For an array of even length, the median is typically computed by finding the average of the two middle elements: 

int medianOfArray(int[] array, int start, int end) {
    Arrays.sort(array); // for safety. This can be ignored
    int mid = (start + end) >>> 1;
    int n = end - start;
    if (n % 2 == 0) {
        int mid2 = mid - 1;
        return (array[mid2] + array[mid]) / 2;
    } else {
        return array[mid];
    }
}

 The median value expects the data set to be in sorted order to be correct. So if we are unsure of the array’s nature, we should first sort the array in ascending or descending order and then find the middle value using any of the previous methods.

Consider a problem statement where we are required to find the median house price of a country. Given the nature of the problem, we can assume that the input data will be too large to fit in the available memory of a conventional computer. If the JVM is not able to load the entire array in memory at a time, it would be difficult to apply the methods mentioned above to find the median. 

In such cases where the data set is too large to fit in memory, we can consider the input to be in a stream rather than a conventional array. We can then find the median of the data stream using additional data structures, such as a Heap with streaming data.

6. Conclusion

In this article, we looked at several approaches to finding the middle elements of an array. We also talked about how this solution can help us find the median of an array. 

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)