Partition方法

博客围绕Java展开,涉及算法与数据结构相关内容。算法和数据结构在Java编程中至关重要,能提升程序性能和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * partition()方法:在基准元素左边的元素都小于基准元素,在基准元素右边的元素都大于等于基准元素。
 *
 * 可以使用partition()方法解决以下常见的问题:
 *
 *  1)查找数组中出现次数超过数组长度一半的元素。
 *      eg:MoreThanHalfSize类中的getElementOfMoreThanHalfSizeByPartition方法。
 *  2)查找数组中最小的(或最大的)k个数 或 查找数组中第k小(或第k大)的数。
 *
 * 优点:时间复杂度为O(n)
 *
 * 缺点:改变了原数组中元素的位置。
 *
 */
public class Partition {


    /**
     * 获取基准元素的下标。
     *
     * @param array 待排序的数组
     * @param left  起点索引
     * @param right 终点索引
     * @return
     */
    public static int partition(int[] array, int left, int right) {

        // 选取数组的头元素作为基准元素
        int pivotPosition = left;           
        int pivot = array[pivotPosition];

        /**
         * 循环结束后:
         *      pivotPosition后面的元素都大于等于基准元素pivot
         *      pivotPosition前面的元素(包括pivotPosition指向的元素)除了基准元素pivot外,其它元素都小于基准元素pivot
         */
        for (int i = pivotPosition + 1; i <= right; i++) { // i表示当前元素的索引

            if (array[i] < pivot) {

                swap(array, pivotPosition, i);
                pivotPosition++;

            }
        }

        /**
         * 目的:
         *      将pivotPosition指向基准元素pivot,并且返回pivotPosition,以确定递归函数quickSort()中left参数与right参数的值
         * 实现:
         *      交换基准元素与pivotPosition当前指向元素的位置。
         */
        if (pivotPosition != left) {
            array[left] = array[pivotPosition];
            array[pivotPosition] = pivot;
        }

        return pivotPosition;
    }


    /**
     * 将数组中下标为indexOfK的元素设为基准元素,即小于基准元素的放在左边,大于或等于基准元素的放在右边。
     *
     * @param array
     * @param left
     * @param right
     * @param indexOfK  基准元素的下标
     */
    public static void makePivotIndexEqualsK(int[] array, int left, int right, int indexOfK) {

        // 基准元素的下标
        int pivotIndex = Partition.partition(array, left, right);

        while (pivotIndex != indexOfK) {

            if (pivotIndex > indexOfK) {
                right = pivotIndex - 1;
            } else {
                left = pivotIndex + 1;
            }
            pivotIndex = Partition.partition(array, left, right);
        }

    }


    /**
     * 数组中,交换两个元素的位置
     */
    private static void swap(int[] array, int i, int j) {
        if (i != j) {
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
    }

    public static void print(int i) {
        System.out.print(i + " ");
    }

}

<think>嗯,用户想了解Guava的Lists.partition方法的功能和用法。我需要先回忆一下Guava库的相关知识。记得Lists.partition是用来将大列表分割成多个小列表的,每个小列表的大小由参数指定。比如一个100个元素的列表,分成每25个一组,得到4个子列表。 接下来,用户需要功能说明和使用示例。功能方面,应该强调这个方法的作用,以及底层是基于subList实现的视图,这样分割后的子列表是原列表的视图,而不是新创建的列表。这一点很重要,因为如果原列表被修改,可能会影响子列表的行为,或者反过来,子列表的操作也可能影响原列表。需要提醒用户注意这一点,避免不当操作导致的问题。 然后,使用示例部分,我应该提供一个简单的Java代码示例,展示如何导入Guava库,创建列表,调用Lists.partition方法,并遍历结果。同时,需要指出子列表是视图,所以修改原列表会影响子列表,比如用户可能不知道这一点,导致并发修改异常或者其他问题。 另外,用户提供的引用中提到了Apache ListUtils.partition和Guava的Lists.partition都基于subList,所以在注意事项里要提到这一点。比如,子列表不支持结构性修改(如增加或删除元素),否则会导致不可预见的错误。还有内存管理的问题,如果原列表很大,分割后的子列表虽然视图,但可能阻止原列表被GC回收,需要及时处理。 然后,生成相关问题。这部分需要根据用户可能感兴趣的点来提问,比如与Apache Commons的对比、子列表视图的影响、实际应用场景、处理大数据量时的注意事项,以及如何避免并发修改异常。这些问题可以帮助用户更深入理解这个方法的使用和潜在问题。 最后,检查是否所有要求都满足,比如行内数学表达式是否正确,独立公式是否单独成段,使用中文回答,引用标识是否正确添加等。确保没有使用任何Markdown格式,代码块正确,并且引用了用户提供的参考文献,特别是引用[1]、[2]中的内容。同时,避免提到自己是如何思考的,保持回答的专业性和结构清晰。</think>### Guava Lists.partition 方法解析 #### 功能说明 `Lists.partition` 是 Google Guava 库提供的一个工具方法,用于将一个大集合按固定大小分割为若干子集合。其底层基于 `List.subList` 实现,因此分割后的子集合是原集合的**视图**(而非独立的新集合),对原集合或子集合的修改可能相互影响[^1][^2]。 #### 核心特性 1. **视图特性** 子集合与原集合共享底层数据,例如修改原集合元素会影响子集合内容,反之亦然。 2. **固定分块** 最后一个子集合可能小于指定分块大小(当总元素数无法整除时)。 3. **不可变性约束** 子集合不支持结构性修改(如增删元素),否则会抛出 `UnsupportedOperationException`[^1]。 #### 使用示例 ```java import com.google.common.collect.Lists; public class PartitionExample { public static void main(String[] args) { // 创建包含100个元素的列表 List<String> originalList = new ArrayList<>(); for (int i = 0; i < 100; i++) { originalList.add("Item-" + i); } // 分割为每25个元素一组 List<List<String>> partitions = Lists.partition(originalList, 25); // 遍历子集合 for (List<String> partition : partitions) { System.out.println("子集合大小: " + partition.size()); System.out.println("首元素: " + partition.get(0)); } } } ``` #### 注意事项 1. **并发修改风险** 若原集合被修改(如增删元素),子集合的遍历可能抛出 `ConcurrentModificationException`。 2. **内存管理** 子集合持有原集合的引用,可能导致大集合无法被垃圾回收,需及时处理子集合[^1]。 3. **性能优化** 适用于批量处理场景(如数据库批量插入),但需注意视图特性带来的副作用[^3]。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值