怎么使用Java函数实现二维数组遍历
导读:本文共2760.5字符,通常情况下阅读需要9分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要:1. 函数方法消减代码层级由于多维数组的遍历层级天然就很深,那么有办法进行消减么?要解决这个问题,关键是要抓住重点,遍历的重点是什么?获取每个元素的坐标!那么我们可以怎么办?定义一个函数方法,输入的就是函数坐标,在这个函数体中执行我们的遍历逻辑即可基于上面这个思路,相信我们可以很容易写一个二维的数组遍历通用方法publicstaticvoidscan(intmaxX,intmaxY,BiConsu... ...
目录
(为您整理了一些要点),点击可以直达。1. 函数方法消减代码层级
由于多维数组的遍历层级天然就很深,那么有办法进行消减么?
要解决这个问题,关键是要抓住重点,遍历的重点是什么?获取每个元素的坐标!那么我们可以怎么办?
定义一个函数方法,输入的就是函数坐标,在这个函数体中执行我们的遍历逻辑即可
基于上面这个思路,相信我们可以很容易写一个二维的数组遍历通用方法
publicstaticvoidscan(intmaxX,intmaxY,BiConsumer<Integer,Integer>consumer){
for(inti=0;i<maxX;i++){
for(intj=0;j<maxY;j++){
consumer.accept(i,j);
}
}
}
主要上面的实现,函数方法直接使用了JDK默认提供的BiConsumer,两个传参,都是int 数组下表;无返回值
那么上面这个怎么用呢?
同样是上面的例子,改一下之后,如:
publicvoidgetEven(){
int[][]cells=newint[][]{{1,2,3,4},{11,12,13,14},{21,22,23,24}};
List<Integer>ans=newArrayList<>();
scan(cells.length,cells[0].length,(i,j)->{
if((cells[i][j]&1)==0){
ans.add(cells[i][j]);
}
});
System.out.println(ans);
}
相比于前面的,貌似也就少了一层而已,好像也没什么了不起的
但是,当数组变为三维、四维、无维时,这个改动的写法层级都不会变哦
2. 遍历中return支持
前面的实现对于正常的遍历没啥问题;但是当我们在遍历过程中,遇到某个条件直接返回,能支持么?
如一个遍历二维数组,我们希望判断其中是否有偶数,那么可以怎么整?
仔细琢磨一下我们的scan方法,希望可以支持return,主要的问题点就是这个函数方法执行之后,我该怎么知道是继续循环还是直接return呢?
很容易想到的就是执行逻辑中,添加一个额外的返回值,用于标记是否中断循环直接返回
基于此思路,我们可以实现一个简单的demo版本
定义一个函数方法,接受循环的下标 + 返回值
@FunctionalInterface
publicinterfaceScanProcess<T>{
ImmutablePair<Boolean,T>accept(inti,intj);
}
循环通用方法就可以相应的改成:
publicstatic<T>TscanReturn(intx,inty,ScanProcess<T>func){
for(inti=0;i<x;i++){
for(intj=0;j<y;j++){
ImmutablePair<Boolean,T>ans=func.accept(i,j);
if(ans!=null&&ans.left){
returnans.right;
}
}
}
returnnull;
}
基于上面这种思路,我们的实际使用姿势如下:
@Test
publicvoidgetEven(){
int[][]cells=newint[][]{{1,2,3,4},{11,12,13,14},{21,22,23,24}};
List<Integer>ans=newArrayList<>();
scanReturn(cells.length,cells[0].length,(i,j)->{
if((cells[i][j]&1)==0){
returnImmutablePair.of(true,i+"_"+j);
}
returnImmutablePair.of(false,null);
});
System.out.println(ans);
}
上面这个实现可满足我们的需求,唯一有个别扭的地方就是返回,总有点不太优雅;那么除了这种方式之外,还有其他的方式么?
既然考虑了返回值,那么再考虑一下传参呢?通过一个定义的参数来装在是否中断以及返回结果,是否可行呢?
基于这个思路,我们可以先定义一个参数包装类:
publicstaticclassAns<T>{
privateTans;
privatebooleantag=false;publicAns<T>setAns(Tans){
tag=true;
this.ans=ans;
returnthis;
}publicTgetAns(){
returnans;
}
}publicinterfaceScanFunc<T>{
voidaccept(inti,intj,Ans<T>ans)
}
我们希望通过Ans这个类来记录循环结果,其中tag=true,则表示不用继续循环了,直接返回ans结果吧
与之对应的方法改造及实例如下:
publicstatic<T>TscanReturn(intx,inty,ScanFunc<T>func){
Ans<T>ans=newAns<>();
for(inti=0;i<x;i++){
for(intj=0;j<y;j++){
func.accept(i,j,ans);
if(ans.tag){
returnans.ans;
}
}
}
returnnull;
}
publicvoidgetEven(){
int[][]cells=newint[][]{{1,2,3,4},{11,12,13,14},{21,22,23,24}};
Stringans=scanReturn(cells.length,cells[0].length,(i,j,a)->{
if((cells[i][j]&1)==0){
a.setAns(i+"_"+j);
}
});
System.out.println(ans);
}
这样看起来就比前面的要好一点了
实际跑一下,看下输出是否和我们预期的一致;
关于“怎么使用Java函数实现二维数组遍历”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。
怎么使用Java函数实现二维数组遍历的详细内容,希望对您有所帮助,信息来源于网络。