Java 自定义对象多维数组给定范围上的流过滤器
最近几天,我尝试了Java8和lambda表达式。实现起来更清晰、更清晰、更有趣,但我一直很困惑如何在给定范围内的多维数组上迭代以找到第一个出现的非null元素。例如,这是我的数组:Java 自定义对象多维数组给定范围上的流过滤器,java,arrays,lambda,java-8,java-stream,Java,Arrays,Lambda,Java 8,Java Stream,最近几天,我尝试了Java8和lambda表达式。实现起来更清晰、更清晰、更有趣,但我一直很困惑如何在给定范围内的多维数组上迭代以找到第一个出现的非null元素。例如,这是我的数组: MyObject[][] array = new MyObject[][]; //this array is never full objects are placed at random places 正如注释所暗示的那样,我试图找到第一个出现的对象或非空对象 array[0-5][irrelevant]
MyObject[][] array = new MyObject[][]; //this array is never full objects are placed at random places
正如注释所暗示的那样,我试图找到第一个出现的对象或非空对象
array[0-5][irrelevant]
or
array[irrelevent][3-9]
到目前为止,我得到的最接近的结果是:
MyObject obj = Arrays.stream(grid.grid)
.flatMap(IntStream.range(0,2)) //here it must work for any dimension given any range
.filter(array -> array != null)
.findFirst()
.orElse(null);
显然,这不会编译,因为它不是整数元素,而是自定义对象。非常感谢您的帮助。我们可以使用以下语法:
MyObject obj = Arrays.stream(array)
.flatMap(Arrays::stream)
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
MyObject findFirst = Arrays.stream(array).flatMap(Arrays::stream)
.collect(Collectors.toList())
.subList(0, 3) // observe this line
.stream()
.filter(e -> e != null).findFirst().orElse(null);
在这里,我们使用flatMap
将2D数组转换为列表
,然后使用子列表
指定要搜索的索引的开始和结束
要指定范围,需要将值传递到
子列表(…)
虽然Nicholas K的答案适用于水平切片,但不适用于垂直切片。这是一个完全符合OP要求的答案。为了清楚起见,我编写了传统的(使用for循环)方法,以确认这就是OP想要做的。然后,我使用流来完成它。它适用于水平和垂直切片
public static void main(String[] args) {
// Sample data
Object[][] array = new Object[5][10];
array[1][5] = "this is it"; // This is the first non-null object
array[4][7] = "wrong one"; // This is another non-null object but not the first one
// Define range (start=inclusive, end=exclusive)
int iStart = 0, iEnd = array.length, jStart = 3, jEnd = 9; // array[irrelevant][3-9]
//int iStart = 1, iEnd = 3, jStart = 0, jEnd = array[0].length; // array[1-3][irrelevant]
// Doing it the traditional way
Object firstNonNull = null;
outerLoop:
for (int i = iStart; i < iEnd; i++)
for (int j = jStart; j < jEnd; j++)
if (array[i][j] != null) {
firstNonNull = array[i][j];
break outerLoop;
}
assert firstNonNull != null;
assert firstNonNull.equals("this is it");
// Doing it with Java 8 Streams
firstNonNull = Arrays.asList(array)
.subList(iStart, iEnd)
.stream()
.flatMap(row -> Arrays.asList(row)
.subList(jStart, jEnd)
.stream()
.filter(Objects::nonNull))
.findFirst()
.orElse(null);
assert firstNonNull != null;
assert firstNonNull.equals("this is it");
}
publicstaticvoidmain(字符串[]args){
//样本数据
Object[][]数组=新对象[5][10];
数组[1][5]=“就是这样”;//这是第一个非空对象
数组[4][7]=“错误的一个”;//这是另一个非空对象,但不是第一个
//定义范围(开始=包含,结束=独占)
int-iStart=0,iEnd=array.length,jStart=3,jEnd=9;//数组[无关][3-9]
//int-iStart=1,iEnd=3,jStart=0,jEnd=array[0]。长度;//数组[1-3][0]
//用传统的方式做
Object firstNonNull=null;
外部环路:
for(int i=iStart;i数组.asList(行)
.子列表(jStart,jEnd)
.stream()
.filter(对象::非空)
.findFirst()
.orElse(空);
assert firstNonNull!=null;
断言firstNonNull.equals(“就是它”);
}
what's grid.grid?这不是lmbda的,这是java流。我们能保证给定的范围是有效的吗?如果给定array[interrelent][3-9]
,实际数据是array[0]=新数组[10]
,但array[1]=空
和array[2]=新数组[4],该怎么办
?它是一个矩形数组,x或y的范围保证在边界内。它与我2小时前的被否决的答案有何不同?在给定的索引范围内看起来如何?这个循环遍历整个arrayOk,这如何允许我在这个矩形阵列上水平或垂直搜索?查看我的示例了解更多详细信息。我们正在将2D数组转换为一维数组。只有水平范围才能工作。告诉我如何为垂直搜索指定范围?我怀疑它是否可行。我将接受这个答案,因为它为我指明了如何做到这一点。是的,有一种可行的方法,因为数组是矩形的,所以如果一个元素在网格上是3,4,那么它就意味着它在位置34,因此在30-40的范围内。我也否决了你,因为你基本上做了和我一样的事情。我特别要求通过一系列index@Eilleen-尼古拉斯一开始给出了完全相同的答案,因此,你在解释问题时可能存在问题。你在他回答的评论中阐明了你需要什么,你也可以在这里这样做。无论如何,非常感谢你给出否决票的理由,非常感谢。