1. Merge and Deduplicate String Array Elements
Given a string array with duplicate elements, split (if needed), deduplicate, and merge. For example:
String[] input = {"array", "merge", "thread", "merge"};
Result: [array, merge, thread]
/**
* Merge and deduplicate a string array (handles split if elements have commas).
* @param input the source array
* @return deduplicated list of strings
*/
private static List<String> mergeAndDeduplicate(String[] input) {
return Arrays.stream(input)
.map(str -> str.split(","))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
}
2. Merge Two Primitive Arrays (Int Arrays Example)
Method 1: Stream-based Merging with Deduplication
Merge two int arrays, sort, deduplicate, and return a new array.
private static int[] mergeAndDeduplicateArrays(int[] source, int[] target) {
if (source.length == 0 && target.length == 0) return new int[0];
if (source.length == 0) return target;
if (target.length == 0) return source;
return IntStream.concat(
Arrays.stream(source).sorted(),
Arrays.stream(target).sorted()
)
.distinct()
.toArray();
}
Method 2: Two-Pointer Technique (In-Place for One Array)
Merge two sorted arrays (in-place into the first array, assuming it has enough space).
/**
* Merge two sorted arrays (nums1 has space for nums2).
* @param nums1 first array (with size m + n)
* @param m valid length of nums1
* @param nums2 second array
* @param n valid length of nums2
*/
public static void mergeSortedArrays(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1, j = n - 1;
int index = m + n - 1; // End of merged array
while (i >= 0 || j >= 0) {
if (i >= 0 && j >= 0) {
nums1[index--] = (nums1[i] >= nums2[j]) ? nums1[i--] : nums2[j--];
} else if (i >= 0) {
nums1[index--] = nums1[i--];
} else {
nums1[index--] = nums2[j--];
}
}
}
3. Merge Two Ordered Collections
import org.apache.commons.collections4.CollectionUtils;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public static List<Integer> mergeOrderedLists(List<Integer> listA, List<Integer> listB) {
if (CollectionUtils.isEmpty(listA) && CollectionUtils.isEmpty(listB)) {
return Collections.emptyList();
}
if (CollectionUtils.isEmpty(listA)) return listB;
if (CollectionUtils.isEmpty(listB)) return listA;
return Stream.of(listA, listB)
.flatMap(Collection::stream)
.distinct()
.sorted()
.collect(Collectors.toList());
}
4. Merge Two Binary Trees (Recursive)
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val) { this.val = val; }
}
public static TreeNode mergeBinaryTrees(TreeNode treeA, TreeNode treeB) {
if (treeA == null && treeB == null) return null;
if (treeA == null) return treeB;
if (treeB == null) return treeA;
TreeNode merged = new TreeNode(treeA.val + treeB.val);
merged.left = mergeBinaryTrees(treeA.left, treeB.left);
merged.right = mergeBinaryTrees(treeA.right, treeB.right);
return merged;
}
5. Merge Two Sorted Linked Lists (Recursive)
class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
}
public static ListNode mergeSortedLists(ListNode listA, ListNode listB) {
if (listA == null) return listB;
if (listB == null) return listA;
if (listA.val <= listB.val) {
listA.next = mergeSortedLists(listA.next, listB);
return listA;
} else {
listB.next = mergeSortedLists(listA, listB.next);
return listB;
}
}
6. Merge Two Maps (Java 8 merge())
import org.apache.commons.collections4.MapUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public static Map<String, Integer> mergeMaps(Map<String, Integer> mapA, Map<String, Integer> mapB) {
if (MapUtils.isEmpty(mapA) && MapUtils.isEmpty(mapB)) {
return Collections.emptyMap();
}
if (MapUtils.isEmpty(mapA)) return mapB;
if (MapUtils.isEmpty(mapB)) return mapA;
Map<String, Integer> result = new HashMap<>(mapA.size() > mapB.size() ? mapA : mapB);
(mapA.size() > mapB.size() ? mapB : mapA).forEach(
(k, v) -> result.merge(k, v, Integer::sum)
);
return result;
}
7. Convert Sorted Array to Binary Search Tree (BST)
class BSTNode {
int val;
BSTNode left, right;
BSTNode(int val) { this.val = val; }
}
public BSTNode sortedArrayToBST(int[] nums) {
return buildBST(nums, 0, nums.length - 1);
}
private BSTNode buildBST(int[] nums, int left, int right) {
if (left > right) return null;
int mid = left + (right - left) / 2; // Avoid overflow
BSTNode root = new BSTNode(nums[mid]);
root.left = buildBST(nums, left, mid - 1);
root.right = buildBST(nums, mid + 1, right);
return root;
}
8. Convert Sorted Linked List to BST
public BSTNode sortedListToBST(ListNode head) {
if (head == null) return null;
return buildBSTFromList(head, null);
}
private BSTNode buildBSTFromList(ListNode left, ListNode right) {
if (left == right) return null;
ListNode mid = findMiddle(left, right);
BSTNode root = new BSTNode(mid.val);
root.left = buildBSTFromList(left, mid);
root.right = buildBSTFromList(mid.next, right);
return root;
}
private ListNode findMiddle(ListNode left, ListNode right) {
ListNode fast = left, slow = left;
while (fast != right && fast.next != right) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
Dubbo Framework: Custom Data Structure Mergers
Dubbo’s Merger SPI allows merging results from multiple service invocations. Here’s how to implement custom mergers:
Merger Interface (SPI)
package com.example.dubbo.merger;
import com.alibaba.dubbo.common.extension.SPI;
@SPI
public interface Merger<T> {
T merge(T... items);
}
Array Mergers (Example: Short Array)
package com.example.dubbo.merger.impl;
import com.example.dubbo.merger.Merger;
public class ShortArrayMerger implements Merger<short[]> {
@Override
public short[] merge(short[]... arrays) {
int totalLength = 0;
for (short[] arr : arrays) {
totalLength += arr.length;
}
short[] result = new short[totalLength];
int index = 0;
for (short[] arr : arrays) {
for (short element : arr) {
result[index++] = element;
}
}
return result;
}
}
Colletcion Mergers (Example: Set)
package com.example.dubbo.merger.impl;
import com.example.dubbo.merger.Merger;
import java.util.HashSet;
import java.util.Set;
public class SetMerger implements Merger<Set<?>> {
@Override
public Set<Object> merge(Set<?>... sets) {
Set<Object> merged = new HashSet<>();
for (Set<?> set : sets) {
if (set != null) {
merged.addAll(set);
}
}
return merged;
}
}
Map Merger
package com.example.dubbo.merger.impl;
import com.example.dubbo.merger.Merger;
import java.util.HashMap;
import java.util.Map;
public class MapMerger implements Merger<Map<?, ?>> {
@Override
public Map<?, ?> merge(Map<?, ?>... maps) {
if (maps.length == 0) return null;
Map<Object, Object> result = new HashMap<>();
for (Map<?, ?> map : maps) {
if (map != null) {
result.putAll(map);
}
}
return result;
}
}
These merger implementations handle different data types (arrays, sets, lists, maps) by concatenating or aggregating elements. The MergerFactory (not shown) caches and loads these mergers for efficient lookup.