Finding the second highest number in array in Java
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Finding the second highest value in a Java array sounds simple until you define the edge cases. The real question is whether you want the second element after sorting or the second distinct value. Most production code and interview problems mean the second distinct value, so the implementation should say that clearly.
Define the Contract First
Before writing code, decide how duplicates behave. For the array [9, 9, 7], one interpretation returns 9 because it is the second element in descending order. The more common interpretation returns 7 because it is the second distinct highest value.
Once that rule is fixed, the code becomes straightforward. The examples below implement the second distinct highest value and throw an exception when no such value exists.
Single-Pass Solution
The most efficient general approach is one scan with two trackers. One variable stores the current highest value, and the other stores the current second distinct highest value.
This runs in O(n) time and uses O(1) extra space. That is better than sorting when you only need one answer.
Why This Loop Works
The loop keeps two facts true while it scans:
- '
highestis the largest value seen so far.' - '
secondHighestis the largest value seen so far that is still smaller thanhighest.'
When a new maximum appears, the old maximum becomes the new candidate for second place. When a value is not the maximum but is still larger than the current second place, it replaces secondHighest.
Using Integer instead of primitive int avoids sentinel values such as Integer.MIN_VALUE, which can break the logic if that value appears in the input.
Sorting Approach
Sorting is often easier to explain, though it is less efficient. It is acceptable when the array is already being copied or sorted for another reason.
This version is easy to read, but it costs O(n log n) time and usually creates a copy so the original array is not mutated.
Testing the Edge Cases
The happy path is not the hard part. The hard part is arrays that make hidden assumptions fail.
Useful test cases include duplicate maximum values, all-identical arrays, negative numbers, very short arrays, and input containing Integer.MIN_VALUE.
When a Stream Is Acceptable
Java streams can express the idea compactly, but they are not usually the clearest or most efficient choice for this specific task. They add boxing, sorting, and intermediate operations for something a plain loop handles directly. If the team prefers streams for consistency, they are still valid, but the one-pass loop is usually the better default.
Common Pitfalls
- Failing to define whether duplicates count toward the second highest result.
- Returning the maximum value again when the requirement was "second distinct highest."
- Using sentinel numeric values and breaking on extreme integer inputs.
- Sorting the array in place when callers expected the original order to remain unchanged.
- Forgetting to handle arrays where all elements are identical.
Summary
- Decide first whether the requirement is second element after sorting or second distinct highest.
- A one-pass scan is the best general solution for the distinct case.
- Sorting works, but it is slower and may mutate input unless you copy the array.
- Edge cases matter more than the basic loop.
- Use clear exceptions when no second distinct value exists.
Related reading
- Finding the second smallest number from the given list using divide-and-conquer
- Finding the shortest path between two points on a grid, using Haskell
- Finding the squares in a plane given n points
- Finding the total number of set-bits from 1 to n
- finding the width of a binary tree
- Finding three elements in an array whose sum is closest to a given number
- findResource returning null when module-info.java is present, why is that?
- FixedThreadPool vs CachedThreadPool the lesser of two evils

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.