I have two lists of objects, say of X and Y.
There is a foreign key in objects of Y which show which object of X they are assigned to. This is a one-to-one relationship, no duplicates. As such, each time a Y object is found, it is not needed in the list anymore.
class X {
Long id;
Y y;
...
}
class Y {
Long id;
Long xId;
...
}
Would it be more efficient to loop through the list of Y for each object of X, or would it be quicker to remove the Y object from its list?
for(X x: xList) {
for(Y y: yList) {
if(y.getXId() == x.getId()) {
x.setY(y);
break;
}
}
}
vs
for(X x: xList) {
for(int i = 0; i < yList.size(); i ) {
Y y = yList.get(i);
if(y.getXId() == x.getId()) {
x.setY(y);
yList.remove(i);
i--;
break;
}
}
}
CodePudding user response:
With respect to time complexity, both are quadratic, O(n2). Your second option might1 be faster in practice, but it is still considered O(n2).
To make it linear, O(n), you have to be willing to spend O(n) extra space.
The below code, builds an auxiliary map having instances of X
keyed by their id.
Map<Long, X> xObjectsById = xList.stream()
.collect(Collectors.toMap(X::getId, Function.identity())));
Then, we can loop through Y
objects and get the corresponding X
from the map.
for (Y y : yList) {
xObjectsById.get(y.getXId())
.setY(y);
}
1 You have measure the performance to conclude this. Moreover, the second option does additional operations of deletion which have to be accounted for. Also how good/bad it performs depends on what sort of list you have.