You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义VektorInt类subvector方法异常:末尾为0/insert仅返回首元素

问题描述

我正在学习类与对象的使用,编写了自定义VektorInt类,已经实现可用的add和insert方法。现在需要实现subvector方法,要求创建一个包含原向量索引a到b-1元素、容量与原向量一致的新向量对象。

目前遇到两个问题:

  • 使用add方法实现时,返回结果接近正确,但末尾元素被替换为0;
  • 使用insert方法实现时,循环提前终止,仅返回第一个元素;最初尝试按数组方式复制插入也得到相同结果。

以下是VektorInt类定义及相关方法:

类定义

public class VektorInt{
    private int[] elementi;
    private int stElementov;

    private static final int START_CAPACITY = 10;
    //konstanta, lahko jo večkrat uporabimo

    public VektorInt(int startCapacity){
        this.elementi = new int[startCapacity];
        this.stElementov = 0;
    }
    public VektorInt() {
        this(START_CAPACITY);
    }
}

相关操作方法

public void set(int index, int value){
    if(index > this.elementi.length){
        throw new IndexOutOfBoundsException();
    }
    this.elementi[index] = value;
}
public void add(int value){
    this.expandIfNeeded();
    this.elementi[this.stElementov] = value;
    this.stElementov++;
}
private void expandIfNeeded(){
    if (this.stElementov >= this.elementi.length){
        int[] stariElementi = this.elementi;
        this.elementi = new int[2*stariElementi.length];
        for(int i = 0; i < this.stElementov; i++){
            this.elementi[i] = stariElementi[i];
        }
        
    }  
}
public void insert(int index, int value){
    this.expandIfNeeded();
    for(int i = this.stElementov - 1; i >= index; i--){
        this.elementi[i + 1] = this.elementi[i];
    }
    this.elementi[index] = value;
    this.stElementov++;
}

有问题的subvector方法

public VektorInt subvector(int start, int end){
    VektorInt subvector = new VektorInt(this.elementi.length);
    for(int i = start; i <= (end) - 1; i++){
        subvector.add(elementi[i]);
    }
    subvector.stElementov++;
    return subvector;
}

调用System.out.println(vektor.subvector(0, 6))返回[2, 3, 4, 5, 6, 1, 0],想请教:替换为insert方法后为何仅返回首元素?初始化足够大的容量为何仍无效?


问题分析与解决

一、使用add时末尾出现0的原因

你当前的subvector方法中,循环结束后多执行了subvector.stElementov++;,这会让stElementov的数值比实际添加的元素数多1。打印向量时会遍历到这个超出实际元素的索引位置,而Java中int数组默认初始化值是0,所以末尾会出现0。

比如你从0到5(end=6,end-1=5)一共添加了6个元素,stElementov原本应为6,加1后变成7,打印时就会取到第7个位置的默认0值。

修复方法:直接删除subvector.stElementov++;这一行。

二、使用insert仅返回首元素的原因

核心问题出在两个地方:

  1. set方法的索引判断错误:你的set方法判断条件是if(index > this.elementi.length),但数组的合法索引范围是0到elementi.length-1,当index等于elementi.length时,判断不会触发异常,但执行elementi[index] = value会直接抛出ArrayIndexOutOfBoundsException,导致循环终止,最终只插入了第一个元素。
  2. insert方法缺少索引合法性检查:如果插入的index超出0到stElementov的范围,会触发上述数组越界问题,或者导致元素插入位置错误。

另外,如果你在循环中错误地固定使用索引0插入元素,每次新元素都会放在最前面,最终结果会是倒序,但不会只返回首元素——这种情况大概率是越界异常导致循环提前中断。

三、初始化容量足够但无效的原因

向量的实际元素数量由stElementov控制,而非数组容量。哪怕初始化了足够大的容量,如果stElementov的数值不正确(比如之前多执行的++操作),打印时会遍历到数组中未赋值的位置,从而出现0或者元素数量错误的情况。

四、正确实现方案

修复后的subvector方法(使用add)

public VektorInt subvector(int start, int end){
    // 先做参数合法性检查,避免索引越界
    if(start < 0 || end > this.stElementov || start >= end){
        throw new IllegalArgumentException("Invalid start or end index");
    }
    VektorInt subvector = new VektorInt(this.elementi.length);
    for(int i = start; i < end; i++){ // 用i < end更直观,替代i <= end-1
        subvector.add(this.elementi[i]);
    }
    return subvector;
}

使用insert的正确实现

public VektorInt subvector(int start, int end){
    if(start < 0 || end > this.stElementov || start >= end){
        throw new IllegalArgumentException("Invalid start or end index");
    }
    VektorInt subvector = new VektorInt(this.elementi.length);
    for(int i = start; i < end; i++){
        // 插入到subvector的当前末尾,等价于add
        subvector.insert(subvector.stElementov, this.elementi[i]);
    }
    return subvector;
}

同步修复set和insert的索引检查

// 修复set方法的索引判断
public void set(int index, int value){
    if(index < 0 || index >= this.stElementov){
        throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.stElementov);
    }
    this.elementi[index] = value;
}

// 给insert方法添加索引合法性检查
public void insert(int index, int value){
    if(index < 0 || index > this.stElementov){
        throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.stElementov);
    }
    this.expandIfNeeded();
    for(int i = this.stElementov - 1; i >= index; i--){
        this.elementi[i + 1] = this.elementi[i];
    }
    this.elementi[index] = value;
    this.stElementov++;
}

内容的提问来源于stack exchange,提问作者Kalina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 12:15:42