For your first question you can optimize your method by only checking collisions with the border bubbles (only the bubbles that are actually exposed and not ones that are entirely surrounded). However, you can optimize this even further by using the fact that you know the coordinates of the bubble to find out approximately (or precisely, with some math) where it's going to hit. Then you can only check collisions with the bubbles in that area. Of course, this will only work if you use a sorted data structure.
A two-dimensional array will work as a sorted structure without much additional effort because it will directly correspond to the ordering in the field. However, there are other structures that you can use, albeit they might be less efficient for this scenario.
For the second question there are many possible solutions. Here's a simple one that I can think of:
Let each bubble have 3 properties: position, color, and group. Position defines the bubble's position in the array, color defines the bubble's color, and group is a reference to an ArrayList of bubbles' positions.
Each time a bubble "hits", check the colors of all bubbles around it. If a bubble with the same color is found, then add the current bubble to it's group.
There are some additional special cases to handle, but I will leave them up to you to figure out.