Without seeing your code, I'd think that the ConcurrentModificationException
s are thrown because you try to remove the group elements from the list or to add them back in while iterating it. Changing a collection while iterating it leads to those exceptions: Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop.
It will get a lot easier if you do not treat the groups as the exception, but as the norm. What I mean by this is that you should convert your List<?>
into a List<List<?>>
where each sub list contains either one element or one of the groups. You can then shuffle that list easily with Collections.shuffle()
and flatten it again.
Look at this rough implementation:
List<Integer> ints = new ArrayList<>(asList(2, 3, 5, 4, 8, 7, 11, 55));
List<List<Integer>> groups = asList(asList(5, 4), asList(7, 11));
// remove all the grouped elements from the list
groups.forEach(ints::removeAll);
// wrap the single elements into list and join them with the groups
List<List<Integer>> wrapped = Stream.concat(ints.stream().map(Arrays::asList),
groups.stream())
.collect(Collectors.toList());
Collections.shuffle(wrapped);
// flatten the list into single elements again
List<Integer> shuffled = wrapped.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println(shuffled); // e.g. [55, 3, 7, 11, 2, 8, 5, 4]
// ----- ----
Note that while this is quite readable, it is probably not the most efficient or error proof solution. But it should give you an idea how to tackle the problem.
Edit after comment from Gonen I. Here is a helper method to only remove the exact sequences and not random parts of them all over the list:
private static <T> void removeSequence(List<T> list, List<T> sequence)
{
int indexOfSubList = Collections.lastIndexOfSubList(list, sequence);
while (indexOfSubList != -1)
{
for (int j = 0; j < sequence.size(); j++)
{
list.remove(indexOfSubList);
}
indexOfSubList = Collections.lastIndexOfSubList(list, sequence);
}
}
Use it by replacing groups.forEach(ints::removeAll);
by groups.forEach(group -> removeSequence(ints, group));