I have an array with multiple arraylists of different sizes.
I want to find the index of the largest arraylist in the array. I tried this:
Collections.max(disc);
disc being the name of the array of arraylists.
ArrayList I believe doesn't implement the Comparable interface so I can't do it like this. Is there a way to make a custom comparable for sizes of ArrayLists?
CodePudding user response:
You can't add interfaces to an existing class. If you want ArrayList
to implement Comparable
, you'll need to write an adaptor class that contains an ArrayList
and implements the interface.
But, in your case, you don't need that. Comparable
has a sister interface called Comparator
which is an external object specifying how to compare some type. It can be used to provide alternative sorting mechanisms (descending rather than ascending, for instance) or, as in your case, to add comparison capabilities to an existing class that lacks them. And Collections.max
has an overload that takes a comparator.
Collections.max(disc, (a, b) -> a.size() - b.size())
Note that if you're on a really old Java version, you'll need to explicitly create a Comparator
instance, rather than using SAM conversion like I do above.
CodePudding user response:
If you want to know the index of the largest sub-ArrayList then you're basically looking for an information relative to where the largest ArrayList is stored. This research is not based solely on the intrinsic characteristics of your biggest ArrayList but also on where it is located.
Using Collections.max won't help you, even if you redefine its natural ordering providing a new Comparator
, because you would only get the largest ArrayList not the index where it is stored. If you want to find the index you have to manually loop the outer ArrayList and whenever you find a new largest sub-ArrayList save its index.
Of course, all of what I said is based on the sole condition that you're interested in retrieving the index and not the biggest sub-ArrayList itself. If you're simply looking for the biggest sub-ArrayList then Collections.max with a Comparator implementation is what you need.
CodePudding user response:
I want to find the index of the largest arraylist in the array.
Collections.max
does not take an array
nor does it return an index
. It returns the large element in a Collection
.
Without knowing your exact data structure I am using a list of lists.
List<List<Integer>> ss =
List.of(
List.of(1, 2, 3),
List.of(1, 2, 3, 4),
List.of(1, 2)
);
This just compares the sizes and returns the index that targets the maximum list
int maxIndex = IntStream.range(0, ss.size()).boxed().collect(Collectors
.maxBy(Comparator.comparing(i -> ss.get(i).size()))).get();
prints
1
The maxBy
Collector returns an Optional
of which I immediately took the value. You may want to assign it to an Optional and then process appropriately for an empty collection.
A simpler way of doing it is with a loop. Just find the max size and associate the index with it.
maxIndex = 0;
int maxSize = 0;
for (int i = 0; i < ss.size(); i ) {
int size = ss.get(i).size();
if (size> maxSize) {
maxIndex = i;
maxSize = size;
}
}
System.out.println(maxIndex);
prints
1
CodePudding user response:
I prefer the more clever solution by WJS, but here is another solution as well. This one here is not as brief but might be easier to comprehend on first reading.
You said:
I have an array with multiple arraylists of different sizes. I want to find the index of the largest arraylist in the array.
As they discussed, Collections.max
returns you a reference to the largest object, not the the index of that object within the array.
So we need two steps:
- Determine the largest element.
- Get the index of that largest object.
First, some example data.
List[] arrayOfListsOfIntegers =
List.of(
List.of( 1 ) ,
List.of( 1001 , 1002 , 1003 , 1004 ) ,
List.of( 101 , 102 , 103 ) ,
List.of( 11 , 12 )
)
.toArray( List[] :: new );
Determine the largest element
Use Arrays.asList
to make a view onto that array that appears as a List
. This way we can call convenient List
methods.
Then make a stream of that list. Sort the elements of the stream by getting each one’s size. Make a new list from the sorted elements. We know the last element of that sorted list has the biggest element.
List sorted =
Arrays
.asList( arrayOfListsOfIntegers )
.stream()
.sorted( Comparator.comparingInt( List :: size ) )
.toList();
Get a reference to that biggest element, the last element of our sorted list of lists.
Object target = sorted.get( sorted.size() - 1 );
Get the index of that largest object
That target object is what we want to locate within our original list. We can locate by calling List#indexOf
. Here again we use Arrays.asList
to mask our array as a List
.
int index = Arrays.asList( arrayOfListsOfIntegers ).indexOf( target );