Thursday, 3 October 2013

Union Multiple Collections into a Single Collection

As developing daily tasks at work, I realize the need of a generic method that merges given an array of collections into a single collection as stated in this StackOverflow Thread.

There are reasonable references to well grounded frameworks (e.g. guava)  and sample implementations in that thread. I also check it out the popular "apache commons collections" that already offers a method that union two collections and returns a single non-modifiable collection; however I think it is not enough. There should be still some improvements to raise the bar to the next level.

 As a result i define the method as follows:

public static <T> Collection<T> union(Collection<T>... collections) {  } 


Implementation is as follows, I hope it helps you...


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import java.util.Iterator;
import java.util.Collection;
 
/**
 * This class offers an alternative implementation for union an array of
 * (java.util.Collection) collections instead of only two collections.
 * CollectionUtils.html#union%28java.util.Collection,%20java.util.Collection%29
 *
 * @author oguzhan.acargil
 * */
public class CollectionUtil {
 
 public static <t> Collection<t> union(Collection<t>... collections) {
  if (hasElements(collections)) {
   int totalSize = totalSizeOf(collections);
   final UnmodifiableCollection<t> union = new UnmodifiableCollection<t>(
     totalSize);
   for (Collection<t> collection : collections) {
    if (hasElements(collection)) {
     union.appendAll(collection);
    }
   }
   return union;
  }
  return null;
 }
 
 private static <t> int totalSizeOf(Collection<t>... collections) {
  int totalSize = 0;
  if (hasElements(collections)) {
   for (Collection<t> collection : collections) {
    if (hasElements(collection)) {
     totalSize += collection.size();
    }
   }
  }
  return totalSize;
 }
 
 private static <t> boolean hasElements(T[] array) {
  if (array != null && array.length > 0) {
   return true;
  } else {
   return false;
  }
 }
 
 private static <t> boolean hasElements(Collection<t> collection) {
  if (collection != null && collection.size() > 0) {
   return true;
  } else {
   return false;
  }
 }
 
 private static class UnmodifiableCollection<t> implements Collection<t> {
 
  private int cursor;
  private int size;
  private Object[] elements;
 
  public UnmodifiableCollection(int totalSize) {
   this.cursor = 0;
   this.size = totalSize;
   this.elements = new Object[totalSize];
  }
 
  private void appendAll(Collection<t> collection) {
   for (T element : collection) {
    elements[this.cursor++] = element;
   }
  }
 
  @Override
  public int size() {
   return this.size;
  }
 
  @Override
  public boolean isEmpty() {
   return this.size > 0;
  }
 
  @Override
  public boolean contains(Object o) {
   if (o != null && !isEmpty()) {
    for (Object element : this.elements) {
     if (o.equals(element)) {
      return true;
     }
    }
   }
   return false;
  }
 
  @Override
  public Iterator<t> iterator() {
   @SuppressWarnings({ "unchecked", "rawtypes" })
   Iterator<t> iterator = new Iterator() {
 
    private int current = -1;
 
    @Override
    public boolean hasNext() {
     return (this.current + 1) < size;
    }
 
    @Override
    public Object next() {
     return elements[++this.current];
    }
 
    @Override
    public void remove() {
     throw new RuntimeException(
       "Iterator.remove() is not supported; "
         + "since this is a non-modifable collection implementation");
    }
   };
   return iterator;
  }
 
  @Override
  public Object[] toArray() {
   return elements;
  }
 
  @SuppressWarnings({ "unchecked", "hiding" })
  @Override
  public <t> T[] toArray(T[] a) {
   if (a != null && !isEmpty()) {
    if (a.length == size()) {
     for (int index = 0; index < a.length; index++) {
      a[index] = (T) elements[index];
     }
    }
   }
   return a;
  }
 
  @Override
  public boolean add(T e) {
   throw new RuntimeException("Collection.add() is not supported; "
     + "since this is a non-modifable collection implementation");
  }
 
  @Override
  public boolean remove(Object o) {
   throw new RuntimeException(
     "Collection.remove(Object o) is not supported; "
       + "since this is a non-modifable collection implementation");
  }
 
  @Override
  public boolean containsAll(Collection c) {
   throw new RuntimeException(
     "Collection.containsAll(Collection c) is not supported; "
       + "since this is a non-modifable collection implementation");
  }
 
  @Override
  public boolean addAll(Collection c) {
   throw new RuntimeException(
     "Collection.addAll(Collection c) is not supported; "
       + "since this is a non-modifable collection implementation");
  }
 
  @Override
  public boolean removeAll(Collection c) {
   throw new RuntimeException(
     "Collection.removeAll((Collection c) is not supported; "
       + "since this is a non-modifable collection implementation");
  }
 
  @Override
  public boolean retainAll(Collection c) {
   throw new RuntimeException(
     "Collection.retainAll(Collection c) is not supported; "
       + "since this is a non-modifable collection implementation");
  }
 
  @Override
  public void clear() {
   throw new RuntimeException("Collection.clear() is not supported; "
     + "since this is a non-modifable collection implementation");
  }
 }
}</t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t>

No comments:

Post a Comment