为List<T>中的T进行参数校验

1、现在前端发送了一个POST请求,他的Data是一个数组,而不是对象(jsonObj的值两侧是中括号)。

var jsonObj = [{'id':11, 'name':'叵'}, {'id':12, 'name':'卜'}];
$.ajax({
    type : "post",
    // 省略
    data : JSON.stringify(jsonObj),
    // 省略
});

 

2、后端的请求方法应该让一个Input的数组对象,或是Input泛型的List对象入参,来进行数据绑定

@RequestMapping
@ResponseBody
public Integer diningId(@RequestBody PersonInput[] inputs) {
    // 省略
    return 0;
}

 

@RequestMapping
@ResponseBody
public Integer diningId(@RequestBody List<PersonInput> inputs) {
    // 省略
    return 0;
}

 

就参数绑定而言,两者都是可行的,参数成功绑定了。

 

3、现在需要做参数校验,比如id不能为空白,

很容易想到在PersonInput.id域的上方追加@NotBlank主键,

在请求方法中追加一个BindingResult对象作为入参。

@RequestMapping
@ResponseBody
public Integer diningId(@RequestBody List<PersonInput> inputs, BindingResult checker) {
    // 省略
    return 0;
}

 

class PersonInput {

    @NotBlank
    private String id;

    private String name;

    // 省略

}

 

4、这样做的话,参数绑定依然能够成功,但是参数校验会失败,checker会是null

 

5、需要追加定义一个新的Pojo,只持有List<PersonInput>对象,并在通过@Valid递归校验。

 

class PersonInputList {

    @Valid
    private List<PersonInput> inputs;

    // 省略

}

转载于:https://www.cnblogs.com/deolin/p/7416398.html

<think>我们被要求解释一个Java方法:publicstatic <T>List<List<T>>splistList(List<T>list,int subNum)方法名似乎是拼写错误,应该是splitList?但根据用户给出的方法名,我们保持原样。功能:将列表拆分为多个子列表,每个子列表最多包含subNum个元素(最后一个子列表可能少于subNum)实现思路:1.创建一个空的列表(List<List<T>>)用于存放结果。2.计算需要拆分成多少个子列表:总元素个数除以每个子列表的大小(向上取整)。3.遍历原列表,每次取出subNum个元素作为一个子列表,添加到结果列表中。注意:如果原列表为空,则返回空列表(或者包含一个空子列表的列表?通常返回空列表)。如果subNum小于等于0,应该抛出异常?但用户方法没有处理,我们按常规处理。我们将写一个规范的实现,并解释代码。代码示例: ```importjava.util.ArrayList;import java.util.List; publicclass ListUtils{/***将列表拆分为多个子列表,每个子列表(除了最后一个)的元素个数为subNum* @param list原列表*@paramsubNum每个子列表的大小(最后一个子列表可能小于此大小)* @param<T>列表元素类型*@return拆分后的子列表集合* @throws IllegalArgumentException如果subNum小于等于0*/public static<T> List<List<T>> splistList(List<T> list, intsubNum) {if(subNum <=0) {thrownew IllegalArgumentException("subNum mustbe greaterthan0");}List<List<T>> result= newArrayList<>();if(list== null|| list.isEmpty()){return result; //返回空列表而不是null}intsize =list.size();//计算子列表的个数intnumOfSublists =(size+ subNum -1) /subNum; //向上取整for (int i=0;i <numOfSublists;i++){intfromIndex =i *subNum;int toIndex =Math.min((i+1)* subNum,size);//防止越界List<T>subList= list.subList(fromIndex, toIndex);result.add(subList);}returnresult;}} ```解释:1.首先检查subNum是否合法(大于0),否则抛出异常。2.如果输入列表为空或null,返回一个空的结果列表(避免返回null,符合最佳实践)。3.计算需要拆分的子列表个数:使用公式`(size +subNum-1)/ subNum`,这是整数除法向上取整的常用技巧。4.循环numOfSublists次,每次取原列表的一个子视图(使用List.subList方法)。注意:subList返回的是原列表的一个视图,所以对子列表的修改会影响原列表。如果不想影响原列表,可以创建新的ArrayList(例如:result.add(newArrayList<>(list.subList(fromIndex, toIndex)));)。5.每个子列表的起始索引是`i*subNum`,结束索引是`(i+1)*subNum`,但最后一个子列表的结束索引不能超过原列表的大小,所以用Math.min取最小值。注意:使用subList得到的子列表是原列表的视图,这意味着如果原列表被修改(比如结构修改,如增加或删除元素),那么子列表的操作可能会抛出ConcurrentModificationException。如果希望子列表独立于原列表,应该创建一个新的列表(如上面注释所述)。根据需求,用户可能希望子列表是独立的,所以我们可以修改为创建新的ArrayList。但原方法没有说明,我们按两种方式解释。修改后的独立子列表版本:```for (int i=0;i <numOfSublists;i++){int fromIndex =i *subNum;int toIndex =Math.min((i+1)* subNum,size);List<T>subList= newArrayList<>(list.subList(fromIndex,toIndex));result.add(subList);} ```但是,原方法名是splistList,我们按照用户给出的方法名,但实现上我们提供两种选择。由于问题中没有明确要求,我们按常规独立子列表实现(避免视图带来的副作用)。因此,完整代码(独立子列表)如下:``` importjava.util.ArrayList;import java.util.List; publicclass ListUtils {publicstatic <T>List<List<T>>splistList(List<T>list,int subNum){if (subNum<=0){throw newIllegalArgumentException("subNummust begreater than0");}List<List<T>>result =new ArrayList<>();if (list ==null ||list.isEmpty()) {returnresult;}intsize =list.size();int numOfSublists= (size +subNum-1)/ subNum;for(inti =0; i< numOfSublists; i++) {intfromIndex =i *subNum;int toIndex =Math.min((i+1)* subNum,size);//创建子列表的独立副本result.add(newArrayList<>(list.subList(fromIndex,toIndex)));}return result;} }```现在,我们按照要求生成相关问题。 §§相关问题§§1.如何避免在拆分列表时创建子列表的独立副本以节省内存?2.除了向上取整,还有哪些方法可以计算子列表的数量?3. Java中List.subList方法使用有哪些注意事项?4.如果原列表非常大,拆分时如何优化内存使用?</think>### Java方法 `splistList` 详解 `public static <T> List<List<T>> splistList(List<T> list, int subNum)` 是一个泛型方法,用于将输入列表 `list` 拆分为多个子列表,每个子列表最多包含 `subNum` 个元素。以下是逐步解析: #### 1. **方法签名** ```java public static <T> List<List<T>> splistList(List<T> list, int subNum) ``` - `<T>`:泛型类型参数,支持任意类型的列表(如 `List<String>`、`List<Integer>`)。 - **输入参数**: - `list`:待拆分的原始列表。 - `subNum`:每个子列表的最大元素数量(必须为正整数)。 - **返回值**:`List<List<T>>`,即包含所有子列表的二维列表。 #### 2. **核心逻辑实现** ```java public static <T> List<List<T>> splistList(List<T> list, int subNum) { if (subNum <= 0) { throw new IllegalArgumentException("subNum must be positive"); } List<List<T>> result = new ArrayList<>(); int size = list.size(); for (int i = 0; i < size; i += subNum) { int endIndex = Math.min(i + subNum, size); List<T> subList = list.subList(i, endIndex); result.add(subList); } return result; } ``` #### 3. **关键步骤解析** - **参数校验**: 若 `subNum <= 0`,抛出 `IllegalArgumentException`,确保子列表大小合法[^1]。 - **子列表生成**: - **循环索引**:`i` 从 `0` 开始,每次递增 `subNum`(如 `subNum=3` 时,`i=0,3,6,...`)。 - **计算结束索引**:`endIndex = min(i + subNum, size)`,防止越界(例如列表末尾不足 `subNum` 个元素时)。 - **截取子列表**:`list.subList(i, endIndex)` 返回原列表的视图(**非独立拷贝**,修改子列表会影响原列表)。 - **结果组装**: 所有子列表按顺序添加到 `result` 中返回。 #### 4. **示例与输出** 假设输入:`list = [A, B, C, D, E]`, `subNum = 2` - **拆分过程**: - `i=0` → 子列表 `[A, B]` - `i=2` → 子列表 `[C, D]` - `i=4` → 子列表 `[E]`(末尾不足 `subNum` 个元素) - **返回值**:`[[A, B], [C, D], [E]]` #### 5. **注意事项** - **原列表修改风险**: `subList()` 返回的是原列表的视图,若通过子列表修改元素(如 `subList.set(0, X)`),原列表同步变化。 - **线程安全**: 非线程安全,多线程环境下需外部同步控制[^2]。 - **空列表处理**: 若输入 `list` 为空,返回空列表(而非 `null`)。 #### 6. **优化建议** 若需子列表独立于原列表(避免修改影响),可创建新列表: ```java result.add(new ArrayList<>(list.subList(i, endIndex))); // 深拷贝 ``` --- ### 相关问题 1. 如何避免子列表修改影响原始列表? 2. Java中还有哪些高效分割集合的工具类(如Guava的`Lists.partition`)? 3. 如何处理多线程环境下的列表拆分操作? [^1]: 参数校验是防御性编程的基础实践。 [^2]: `ArrayList` 非线程安全,需外部同步(如 `synchronized` 块)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值