[ 
https://issues.apache.org/jira/browse/GROOVY-11649?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17949224#comment-17949224
 ] 

Paul King edited comment on GROOVY-11649 at 5/4/25 4:25 AM:
------------------------------------------------------------

The {{partitionPoint}} method is handy when you have some kind of partitioned 
aggregate and you want to insert into the aggregate while maintaining the 
partitions. Often, this will mean you have a sorted list and you want to insert 
while maintaining the sort order.

Groovy's sort variants give you lists that could benefit from this method. 
Consider this example (we'll use the mutating variant):
{code:groovy}
def even = { it % 2 == 0 }
def odd = { it % 2 != 0 }

def list = [4, 7, 15, 12, 6, 3, 5]
list.sort(even)
assert list == [7, 15, 3, 5, 4, 12, 6]
{code}
Now supposed we want to add more numbers into this list. We can add them and 
resort, but {{partitionPoint}} let's us know where to add to retain the sorted 
properties:
{code:groovy}
def additions = [1, 6, 8, 7]
additions.each {
    def idx = list.partitionPoint(odd)
    list.add(idx, it)
}
assert list == [7, 15, 3, 5, 1, 7, 8, 6, 4, 12, 6]
{code}
It is also useful for working with the partitions:
{code:groovy}
def idx = list.partitionPoint(odd)
assert list[0..<idx].every(odd)
assert list[idx..-1].every(even)
{code}
Does Java offer some better way to do this? It does offer the {{PriorityQueue}} 
and this means there is no need for {{partitionPoint}} to insert into such a 
collection, but it is a little cumbersome to use:
{code:groovy}
def evenComparator = { a, b -> (a % 2 == 0) <=> (b % 2 == 0) }
def ordered = new PriorityQueue(evenComparator)
ordered.addAll([4, 7, 15, 12, 6, 3, 5])
ordered.addAll(additions)
println ordered.toList() // [7, 1, 15, 4, 7, 3, 5, 12, 6, 8, 6]
while(!ordered.empty) {
    println ordered.poll()
} // 7 1 7 15 3 5 6 6 4 12 8
assert ordered.empty
{code}
The standard iterator ordered doesn't follow the priority. The "poll" method 
can be used but the queue will be exhausted of elements after using it.

What about arrays? We can sort non-primitive arrays (and processing can make 
use of {{partitionPoint}}):
{code:groovy}
Integer[] array = [4, 7, 15, 12, 6, 3, 5]
array.sort(true, evenComparator)
assert array == [7, 15, 3, 5, 4, 12, 6]
idx = array.partitionPoint(odd)
assert array[0..<idx].every(odd)
assert array[idx..-1].every(even)
{code}
But, we currently don't have sort variants for primitive arrays. Arrays.sort is 
available without the comparator, but no variant with comparators exist. This 
alone doesn't make partitionPoint less useful, but since arrays are of fixed 
size, we also don't have the ability to insert an extra into an array at a 
given index. I think this makes {{partitionPoint}} less useful for arrays in 
general.


was (Author: paulk):
The {{partitionPoint}} method is handy when you have some kind of partitioned 
aggregate and you want to insert into the aggregate while maintaining the 
partitions. Often, this will mean you have a sorted list and you want to insert 
while maintaining the sort order.

Groovy's sort variants give you lists that could benefit from this method. 
Consider this example (we'll use the mutating variant):
{code:groovy}
def even = { it % 2 == 0 }
def odd = { it % 2 != 0 }

def list = [4, 7, 15, 12, 6, 3, 5]
list.sort(even)
assert list == [7, 15, 3, 5, 4, 12, 6]
{code}
Now supposed we want to add more numbers into this list. We can add them and 
resort, but {{partitionPoint}} let's us know where to add to retain the sorted 
properties:
{code:groovy}
def additions = [1, 6, 8, 7]
additions.each {
    def idx = list.partitionPoint(odd)
    list.add(idx, it)
}
assert list == [7, 15, 3, 5, 1, 7, 8, 6, 4, 12, 6]
{code}
It is also useful for working with the partitions:
{code:groovy}
def idx = list.partitionPoint(odd)
assert list[0..<idx].every(odd)
assert list[idx..-1].every(even)
{code}
Does Java offer some better way to do this? It does offer the {{PriorityQueue}} 
and this means there is no need for {{partitionPoint}} to insert into such a 
collection, but it is a little cumbersome to use:
{code:groovy}
def evenComparator = { a, b -> (a % 2 == 0) <=> (b % 2 == 0) }
def ordered = new PriorityQueue(evenComparator)
ordered.addAll([4, 7, 15, 12, 6, 3, 5])
ordered.addAll(additions)
println ordered.toList() // [7, 1, 15, 4, 7, 3, 5, 12, 6, 8, 6]
while(!ordered.empty) {
    println ordered.poll()
} // 7 1 7 15 3 5 6 6 4 12 8
assert ordered.empty
{code}
The standard iterator ordered doesn't follow the priority. The "poll" method 
can be used but the queue will be exhausted of elements after using it.

What about arrays? We can sort non-primitive arrays:
{code:groovy}
Integer[] numsArr = [4, 7, 15, 12, 6, 3, 5]
assert numsArr.sort(evenComparator) == [7, 15, 3, 5, 4, 12, 6]
{code}
But, we currently don't have sort variants for primitive arrays. Arrays.sort is 
available without the comparator, but no variant with comparators exist. This 
alone doesn't make partitionPoint less useful, but since arrays are of fixed 
size, we also don't have the ability to insert an extra into an array at a 
given index. I think this makes {{partitionPoint}} less useful for arrays.

> Create partitionPoint extension method variants
> -----------------------------------------------
>
>                 Key: GROOVY-11649
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11649
>             Project: Groovy
>          Issue Type: New Feature
>            Reporter: Paul King
>            Assignee: Paul King
>            Priority: Major
>             Fix For: 5.x
>
>
> See: https://github.com/apache/groovy/pull/2210



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to