Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 79 additions & 9 deletions java/src/main/java/com/optimizeme/CollectionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,91 @@
public class CollectionUtils {

public static <T extends Comparable<T>> List<T> mergeSorted(List<T> a, List<T> b) {
List<T> result = new ArrayList<>(a.size() + b.size());
int i = 0, j = 0;
while (i < a.size() && j < b.size()) {
if (a.get(i).compareTo(b.get(j)) <= 0) {
int na = a.size();
int nb = b.size();
List<T> result = new ArrayList<>(na + nb);

// Fast path for random-access lists: avoid duplicate get() calls by caching current elements
if (a instanceof java.util.RandomAccess && b instanceof java.util.RandomAccess) {
if (na == 0) {
if (nb > 0) result.addAll(b);
return result;
}
if (nb == 0) {
if (na > 0) result.addAll(a);
return result;
}
int i = 0, j = 0;
T aval = a.get(0);
T bval = b.get(0);
while (i < na && j < nb) {
if (aval.compareTo(bval) <= 0) {
result.add(aval);
i++;
if (i < na) {
aval = a.get(i);
}
} else {
result.add(bval);
j++;
if (j < nb) {
bval = b.get(j);
}
}
}
while (i < na) {
result.add(a.get(i++));
} else {
}
while (j < nb) {
result.add(b.get(j++));
}
return result;
}

// Generic path for non-random-access lists: use iterators to get O(n) traversal
java.util.Iterator<T> ita = a.iterator();
java.util.Iterator<T> itb = b.iterator();

if (!ita.hasNext()) {
while (itb.hasNext()) {
result.add(itb.next());
}
return result;
}
while (i < a.size()) {
result.add(a.get(i++));
if (!itb.hasNext()) {
while (ita.hasNext()) {
result.add(ita.next());
}
return result;
}
while (j < b.size()) {
result.add(b.get(j++));

T aval = ita.next();
T bval = itb.next();

while (true) {
if (aval.compareTo(bval) <= 0) {
result.add(aval);
if (ita.hasNext()) {
aval = ita.next();
} else {
// drain remaining from b (including current bval)
result.add(bval);
while (itb.hasNext()) result.add(itb.next());
break;
}
} else {
result.add(bval);
if (itb.hasNext()) {
bval = itb.next();
} else {
// drain remaining from a (including current aval)
result.add(aval);
while (ita.hasNext()) result.add(ita.next());
break;
}
}
}

return result;
}

Expand Down
Loading