I need some code sample or algorithm to resize List<List<Integer>>
that should work in next way:
Let's imagine that we have next newSize
and incomingList
(pseudocode):
int newSize = 4;
List<List<Integer>> incomingList = List(List(1,2,3),List(4,5,6),List(7,8,9);
List<List<Integer>> result = resizeListOfNestedList(newSize, incomingList)
newSize
integer sets new size of incomingList
and resizeListOfNestedList
should return next result for non odd numbers (eg. 4):
List(List(1,2),List(3,4),List(5,6),List(7,8)
and next if newSize is odd number (e.g 3):
List(List(1,2),List(3,4,5),List(6,7,8)
newSize
is always greater than incomingList.size()
I would appreciate any advice.
Update
With help of google.common.Lists
, I have finished draft code (yeah, it smells), I hope it will help somebody.
In my case method receives different incomingList.size()
s and newSize
params and it's obvious that incomingList.size()/newSize
will return double value (e.g incoming list.size() = 1000, but we need to "compress" it to 600 elements) so I am not able to use Lists.partition
all the time. expandList
is better to call after next code:
int maxSplitValue = (int) Math.ceil((double) incomingList.size() / newSize);
List<List<Integer>> firstPortionValues = Lists.partition(
incomingList, maxSplitValue
);//size can be less than required after double to int upper round
if (firstPortionValues.size() < maxSplitValue) {
List<List<Integer>> expandedList = expandList(firstPortionValues, maxSplitValue)
}
Results:
Incoming list:[[0, 1], [2, 3]]
New size value: 3
Outcoming list:[[0], [1], [2, 3]]
Incoming list:[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]
New size value: 4
Outcoming list:[[0.0], [1.0], [2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]
Code:
public List<List<Integer>> expandList(List<List<Integer>> incomingList, int newSize) {
List<List<Integer>> resultList = new ArrayList<>();
for (int index = 0; index < incomingList.size(); index++) {
List<Integer> nodeList = incomingList.get(index);
final int minPortionValue = getMinPortionValue(
incomingList.size(), resultList.size(), nodeList.size(), index, newSize
);
List<List<Integer>> portionResult = splitNodeList(new ArrayList<>(nodeList), minPortionValue);
resultList.addAll(portionResult);
}
return resultList;
}
private int getMinPortionValue(int listSize, int resultListSize, int listElementSize, int index, int newSize) {
if (listElementSize > 1) {
int maxPortionValue = listElementSize % 2 == 0 ? listElementSize / 2 : --listElementSize;
boolean isOkUseMaxPortionValue = maxPortionValue + listSize - index + resultListSize <= newSize;
if (isOkUseMaxPortionValue) {
return maxPortionValue;
} else {
return getMinPortionValue(listSize, resultListSize, listElementSize - 1, index, newSize);
}
} else {
return 0;
}
}
private List<List<Integer>> splitNodeList(List<Integer> nodeList, int minSplitValue) {
List<List<Integer>> result = new ArrayList<>();
if (minSplitValue > 0) {
result.addAll(Lists.partition(nodeList, minSplitValue));
return result;
} else {
result.add(nodeList);
return result;
}
}