0 votes
1 view
in Java by (3.6k points)

I have this code:

public static String SelectRandomFromTemplate(String template,int count) {

   String[] split = template.split("|");

   List<String> list=Arrays.asList(split);

   Random r = new Random();

   while( list.size() > count ) {

      list.remove(r.nextInt(list.size()));

   }

   return StringUtils.join(list, ", ");

}

I get this:

06-03 15:05:29.614: ERROR/AndroidRuntime(7737): java.lang.UnsupportedOperationException

06-03 15:05:29.614: ERROR/AndroidRuntime(7737):     at java.util.AbstractList.remove(AbstractList.java:645)

How would be this the correct way? Java.15

1 Answer

0 votes
by (35.8k points)

There are some problems with your code :

1.  On Arrays.asList executing a fixed-size list

From API:

Arrays.asList: Returns a fixed-size list backed by the specified array.

This means that you can not add to it; you can not remove from it. You can not structurally alter the List.

Solution:

Build a LinkedList, which promotes faster remove.

List<String> list = new LinkedList<String>(Arrays.asList(split));

2. On split taking regex

From API:

String.split(String regex): Splits this string around matches of the given regular expression.

| is a regex metacharacter; if you require to break on a literal |, you need to avoid it to \|, which as a Java string literal is "\\|".

solution:

template.split("\\|")

Alternatively, Rather than calling remove one at a time with arbitrary indices, it's more satisfying to create enough random numbers in the range, and then crossing the List once with a listIterator(), calling remove() at relevant indices. 

By this, your algorithm would be O(N).

Hope this helps…!!

...