Convert comma separated String to List
List<String> items = Arrays.asList(str.split("\\s*,\\s*"));
The above code splits the string on a delimiter defined as: zero or more whitespace, a literal comma, zero or more whitespace which will place the words into the list and collapse any whitespace between the words and commas.
Please note that this returns simply a wrapper on an array: you CANNOT for example .remove() from the resulting List. For an actual ArrayList you must further use new ArrayList<String>.
Convert comma separated String to List
List<String> items = Arrays.asList(str.split("\\s*,\\s*"));
The above code splits the string on a delimiter defined as: zero or more whitespace, a literal comma, zero or more whitespace which will place the words into the list and collapse any whitespace between the words and commas.
Please note that this returns simply a wrapper on an array: you CANNOT for example .remove() from the resulting List. For an actual ArrayList you must further use new ArrayList<String>.
Arrays.asList returns a fixed-size List backed by the array. If you want a normal mutable java.util.ArrayList you need to do this:
List<String> list = new ArrayList<String>(Arrays.asList(string.split(" , ")));
Or, using Guava:
List<String> list = Lists.newArrayList(Splitter.on(" , ").split(string));
Using a Splitter gives you more flexibility in how you split the string and gives you the ability to, for example, skip empty strings in the results and trim results. It also has less weird behavior than String.split as well as not requiring you to split by regex (that's just one option).
String[] list = "your string".split(",");
For listView:
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,android.R.layout.simple_list_item_1,list);
yourListViewvariable.setAdapter(adapter);
Update for spinner:
private Spinner spinner = (Spinner)findViewById(R.id.yourSpinnerId);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,android.R.layout.simple_spinner_item,list);
adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
You can try this way:
String input = "actif,fernando,enrique";
try {
String[] splitArray = input.split(",");
for(String s : splitArray){
yourAdapter.add(s);
}
} catch (PatternSyntaxException ex) {
}
Assuming that your adapter is of type String
java - Split List<String[]> into List<List<String[]>> - Code Review Stack Exchange
java - How to convert a String into an ArrayList? - Stack Overflow
java - convert comma separated string to list without intermediate container - Stack Overflow
Java 8 convert String of ints to List<Integer> - Stack Overflow
Motivations for improvement
I think "solving in 1 or 2 statements" is not a good target. Aiming for Java 8 features for the sake of using Java 8 features is also not a good target. A better target would be a combination of:
- correct and reasonably robust
- easy to understand
- reasonably efficient
Here's a bit shorter and more efficient, but pretty bad solution:
private List<List<String[]>> splitIntoBlocks(List<String[]> rows) {
List<List<String[]>> blocks = new ArrayList<>();
int start = 0;
for (int index = 0; index < rows.size(); index++) {
String marker = rows.get(index)[0];
if (marker.equals("3000")) {
start = index;
} else if (marker.equals("3900")) {
int end = index + 1;
blocks.add(rows.subList(start, end));
}
}
return blocks;
}
This is bad (as bad as the original code), because it doesn't validate the input. It will only work correctly with input in the assumed format, which it doesn't verify, and it doesn't detect or signal when something is wrong, which could lead to nasty bugs.
Validating inputs
The posted code assumes the input follows a certain format. It should at least document the assumptions, and state if the caller can be trusted to enforce those assumptions.
As you mentioned, the input comes from CSV files. Since the expected format is not captured by the List<String[]> type, I would be very cautious. A verification is needed somewhere to avoid bugs or undefined behavior, for example the following checks come to mind:
- There are the same number of START and END markers (you already did this one)
- The START and END markers don't overlap
- (optional?) There are no garbage records after an END and before the next START
- The rows are not empty (avoid crashing due to index out of bounds exceptions)
When any of these assumptions fail, I would either raise a custom exception that the caller can handle, or else throw IllegalArgumentException to fail fast.
So in fact, instead of making the posted code shorter, I'm suggesting to actually make it longer, by adding more validation logic.
Making the code easier to understand
Another answer already mentioned to improve the variable names. (I suggest following Java conventions with camelCase names, so startIndices and endIndices.)
The values "3000" and "3900" are magic strings. It would be better to use private static final constants for such values, so that they stand out, and with a descriptive name.
Building the lists of startIndices and endIndices use the same logic, duplicated. It would be good to extract to a helper method.
When returning a container type, it's usually more practical to return an empty container instead of null.
Low hanging fruit
l1 and l2 are very opaque variable names. start_indices and end_indices would be much more descriptive.
//get all position of 3000
List<Integer> l1 = IntStream.range(0,rows.size())
.filter(i->rows.get(i)[0].equals("3000"))
.boxed()
.collect(Collectors.toList());
This code takes int indices, boxes them into Integer indices, and collects them into a List<Integer>. This results in many small objects in memory.
We can avoid the boxing, by replacing .boxed().collect(Collectors.toList()) with .toArray() and changing the variable type to int[].
// get positions of all "3000"'s
int[] start_indices = IntStream.range(0,rows.size())
.filter(i->rows.get(i)[0].equals("3000"))
.toArray();
Apply similar change to the group end indices, and corresponding changes to the final res construction.
Single Pass
The above is still passing over the rows input 3 times; the first to collect the starting indices, the second to collect the ending indices, and the third time to assemble the result. Three passes means you cannot apply this grouping operation on an ephemeral stream; it requires a concrete collection that can be repeatedly iterated over.
Moreover, an IntStream is being used to generate indices into the rows list -- a hack -- which requires an ArrayList or similar \$O(1)\$-indexable collection to avoid quadratic time complexity.
It would be much better to perform a single pass over the stream of data, and collecting the required groups along the way:
private List<List<String[]>> splitIntoBlocks(List<String[]> rows) {
return rows.stream().collect(Block.collector());
}
Well, the above clearly solves the "looking for someone to solve this in perhaps 1 or 2 statements" request, but clearly additional work is still required. The Block.collector() class is required, writing of which (to handle possible splitting & parallel stream handling) is a non-trivial exercise. See Collector.of(...)
Try something like
List<String> myList = new ArrayList<String>(Arrays.asList(s.split(",")));
Arrays.asListdocumentationString.splitdocumentationArrayList(Collection)constructor documentation
Demo:
String s = "lorem,ipsum,dolor,sit,amet";
List<String> myList = new ArrayList<String>(Arrays.asList(s.split(",")));
System.out.println(myList); // prints [lorem, ipsum, dolor, sit, amet]
String s1="[a,b,c,d]";
String replace = s1.replace("[","");
System.out.println(replace);
String replace1 = replace.replace("]","");
System.out.println(replace1);
List<String> myList = new ArrayList<String>(Arrays.asList(replace1.split(",")));
System.out.println(myList.toString());
If you're using Java 8, you can:
int[] numbers = Arrays.asList(numbersArray.split(",")).stream()
.map(String::trim)
.mapToInt(Integer::parseInt).toArray();
If not, I think your approach is the best option available.
Using java 8 Streams:
List<Integer> longIds = Stream.of(commaSeperatedString.split(","))
.map(Integer::parseInt)
.collect(Collectors.toList());
You need to split the string and make a Stream out of each parts. The method splitAsStream(input) does exactly that:
Pattern pattern = Pattern.compile(", ");
List<Integer> list = pattern.splitAsStream(ints)
.map(Integer::valueOf)
.collect(Collectors.toList());
It returns a Stream<String> of the part of the input string, that you can later map to an Integer and collect into a list.
Note that you may want to store the pattern in a constant, and reuse it each time it is needed.
Regular expression splitting is what you're looking for
Stream.of(ints.split(", "))
.map(Integer::parseInt)
.collect(Collectors.toList());
Having stream, you can simply "flatMap" further and return the result:
return combinedStream
.flatMap(str -> Arrays.stream(str.split("\\P{L}")))
.collect(Collectors.toList());
To put it altogether:
private List<String> getWordList(List<String>... lists) {
return Stream.of(lists)
.flatMap(Collection::stream)
.flatMap(str -> Arrays.stream(str.split("\\P{L}")))
.collect(Collectors.toList());
}
You don't need to introduce so many variables :
private List<String> getWordList(List<String>... lists) {
return Stream.of(lists) // Stream<Stream<String>>
.flatMap(Collection::stream) // Stream<String>
.flatMap(Pattern.compile("\\P{L}")::splitAsStream) //Stream<String>
.collect(toList()); // List<String>
}
As underlined by Holger, .flatMap(Pattern.compile("\\P{L}")::splitAsStream)
should be favored over .flatMap(s -> Arrays.stream(s.split("\\P{L}"))) to spare array allocation and pattern compilation performed for each element of the stream.