[英]iterating through multidimensional ArrayList
我对于遍历多维ArrayList感到困惑。 我看到了一些有关它的话题,它们看起来很复杂。 具体来说,这里是公认的答案: 如何使用迭代器遍历二维ArrayList? 可以像这种方法吗? 它遍历arrayList并将值复制到数组:
private void reassembleArray(int[] array, ArrayList<ArrayList<Integer>> buckets) {
Iterator<ArrayList<Integer>> it = buckets.iterator();
int i = 0;
while (it.hasNext()) {
ArrayList<Integer> intList = it.next();
Iterator<Integer> itInteger = intList.iterator();
while (itInteger.hasNext()) {
array[i] = itInteger.next();
i++;
}
}
}
使用这种简单形式会有任何危险或副作用吗?
这是完整的程序,它是一种称为基数排序的排序算法的实现。
import java.util.ArrayList;
import java.util.Iterator;
/**
* Radix sort implementation
*/
public class RadixSort {
/**
* Runs the program
*/
public static void main(String[] args) {
int[] array = {315, 418, 591, 260, 533, 58, 976, 938,};
System.out.println("Radix sort implementation");
printArray(array);
sort(array, 3); // 3 is the maximun number of digits in all array elements to sort
printArray(array);
}
/*
* sort array of integers using radix sort algorithm
* @param array The array
* @param n the maximum number of digits in array elements
*/
private void sort(int[] array, int n) {
int digitNumber = 0;
while (digitNumber < n) {
ArrayList<ArrayList<Integer>> buckets = initBuckets();
// store each element in the bucket corresponding to the (digitNumber + 1)th
// digit of that element
for (int i = 0; i < array.length; i++) {
int value = array[i];
int bucket = (value / (int) (Math.pow(10, digitNumber))) % 10;
buckets.get(bucket).add(value);
}
reassembleArray(array, buckets);
digitNumber++;
}
}
/*
* Initialize buckets ArrayList
* @return The buckets ArrayList
*/
private ArrayList<ArrayList<Integer>> initBuckets() {
ArrayList<ArrayList<Integer>> buckets = new ArrayList<ArrayList<Integer>>();
// a bucket for each digit from 0 to 9
for(int i = 0; i < 10; i++) {
buckets.add(new ArrayList<Integer>());
}
return buckets;
}
/*
* Reassemble the array
* @param array The array
* @param buckets The buckets
*/
private void reassembleArray(int[] array,
ArrayList<ArrayList<Integer>> buckets) {
Iterator<ArrayList<Integer>> it = buckets.iterator();
int i = 0;
while (it.hasNext()) {
ArrayList<Integer> intList = it.next();
Iterator<Integer> itInteger = intList.iterator();
while (itInteger.hasNext()) {
array[i] = itInteger.next();
i++;
}
}
}
/*
* Prints an array of integers on a single line
* @param array The array
*/
private void printArray(int[] array) {
System.out.print("array: {");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ((i == array.length - 1) ?"" : ", "));
}
System.out.println("}");
}
}
该算法仅需要通过多个步骤对集合进行排序,首先根据右边的第一个数字对集合进行排序,并根据最后一个数字将所有最差值在0-9的元素保持不变,同时保持集合的初始顺序,然后从存储区0开始再次重新集合,然后根据左侧的下一个数字进行排序,依此类推。
该程序可以正常工作,并对收藏进行排序。
我敢打赌,您得到的输出与您期望的输出不同,因为以下行会导致:
array[i] = itInteger.next();
类型不匹配:无法从Integer转换为int []
据我了解,您想将List<List<Integer>>
结构转换为相同类型的数组。 您还需要使用Stream::mapToInt
将Integer
映射到int
:
int array[][] = new int[buckets.size()][];
IntStream.range(0, buckets.size())
.forEach(i -> array[i] = buckets.get(i)
.stream()
.mapToInt(j -> j.intValue())
.toArray());
System.out.println(Arrays.deepToString(array)); // Prints the very same output
同样,您不需要使用Iterator
,但是如果您坚持使用它:
int outerIndex = 0;
while (outerIterator.hasNext()) {
List<Integer> list = outerIterator.next();
Iterator<Integer> innerIterator = list.iterator();
array[outerIndex] = new int[list.size()];
int innerIndex = 0;
while (innerIterator.hasNext()) {
array[outerIndex][innerIndex] = innerIterator.next().intValue();
innerIndex++;
}
outerIndex++;
}
使用这种简单形式会有任何危险或副作用吗?
是的,这两种解决方案都是因为它们既不修改原始输入资源也不影响其他资源。
如果使用增强的for循环而不是迭代器,则代码将更加清晰:
int i = 0;
for (List<Integer> intList : buckets) {
for (int value : intList) {
arr[i++] = value;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.