I have an ArrayList that contains a messageId, then a -, then a username.
Example : E123-sam
I want to divide each element of my List such that the part before the - goes to one ArrayList and the part after that goes to an other ArrayList.
How can I do it?
Assuming you have these ArrayLists:
List<String> allStrings;
// ... initialization and filling of 'allStrings'
List<String> messageIDs = new ArrayList<>();
List<String> userNames = new ArrayList<>();
you can loop through elements of the ArrayList and use String#split(delimiter) to separate the string based in the delimiter:
for (String s : allStrings) {
String[] parts = s.split("-");
messageIDs.add(parts[0]);
userNames.add(parts[1]);
}
Note: This will work if all the strings in allStrings follows the pattern "something-something". If not, then you can check if the length of parts is correct before accessing its elements, otherwise you will get a IndexOutOfBoundsException.
If you plan to use Java 8, you could do:
List<String> listOfIds = original.stream().map(e -> e.split("-")[0]).collect(Collectors.toList());
List<String> listOfUsernames = original.stream().map(e -> e.split("-")[1]).collect(Collectors.toList());
Related
I'm have defined a list like the below
List<String> list = List.of("val1", "val2", "val3");
Now I have the below String
String myStr = "rel1,wel12,val1";
Now I need to check if the String has anyone one of the elements of the list(in the above case its true as it has val1, next is get that value into a variable
I have tried the below and it works, but I'm sure there is a better way to do that using any of the Collections libraries
List<String> list = List.of("val1", "val2", "val3");
String myStr = "rel1,wel12,val1";
String matchedStr =StringUtils.EMPTY;
String[] vals = myStr.split(",");
for(String val:vals) {
if(list.contains(val){
matchedStr=val;
break;
}
}
You can use Java Streams to get the first String that match:
Optional<String> result = Stream.of(vals).filter(list::contains).findFirst();
Your way is alright if the lists aren't too big. I am considering the string as a list too because it can be made one from splitting it as you've done already. You can make a set from the bigger one, and iterate on the smaller one.
Another way to go would be to find the intersection of two lists.
List<String> list = Arrays.asList("red", "blue", "blue", "green", "red");
List<String> otherList = Arrays.asList("red", "green", "green", "yellow");
Now we can find the inttersection:
Set<String> result = list.stream()
.distinct()
.filter(otherList::contains)
.collect(Collectors.toSet());
The result should contain "red" and "green".
Some more info on collectors.
Depending on the possible values in the problem domain, there may be no need to split the input string. Just call String#contains.
If so, you can flip your logic. Rather than loop on the split parts, loop on the target list of strings. For each string in the list, ask if your unprocessed input string contains that element. If yes, bail out of the loop.
Tip: If this code is in a method returning a string, and returns null if no match was found, learn about returning an Optional.
I would favour Zobayer's answer, or using List#retainAll.
final List<String> first = List.of("one", "two", "three");
final List<String> out = new ArrayList<>(Arrays.asList("five,four,three".split(",")));
out.retainAll(first);
out contains the single entry, "three".
Very simple question, I have
List<String> forbidden_words = Arrays.asList("test","one","two");
List<String> list1 = Arrays.asList("eiofjfrgj_test","oiione","rrrtwo", "normal", "word");
I want to remove the elements in list1 that contain forbidden words so I get "normal" & "word" in list1. What's the best way to do this?
Here's how I would write that:
List<String> forbiddenWords = Arrays.asList("test","one","two");
List<String> words = Arrays.asList("eiofjfrgj_test","oiione","rrrtwo", "normal", "word");
List<String> filtered = words.stream()
.filter(word -> !forbiddenWords.stream().anyMatch(forbiddenWord -> word.contains(forbiddenWord)))
.collect(Collectors.toList());
System.out.println(filtered);
Use regex and removeIf():
// Input from question
List<String> forbidden_words = Arrays.asList("test","one","two");
List<String> list1 = Arrays.asList("eiofjfrgj_test","oiione","rrrtwo", "normal", "word");
// Make list1 mutable
list1 = new ArrayList<>(list1);
// Remove forbidden words using regex, so it works case-insensitively
Pattern p = Pattern.compile(forbidden_words.stream().map(Pattern::quote).collect(Collectors.joining("|")),
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
list1.removeIf(s -> p.matcher(s).find());
// See result
System.out.println(list1);
Output
[normal, word]
String array is immutable (or to be precise: fixed). The only way to do that is to convert the string array to a List (using Arrays.asList()), remove the "forbidden" word and finally convert the list back to String array (using the method toArray())
To begin with, most other answer answers are not efficient but are short.
Below is another possible way you would do it.
public static String[] naiveFiltering(String[] forbidden_words, String[] list1 ){
List<String> filteredList = new ArrayList<>(); //extra memory
for(String str: list1){
boolean containsForbidden = false;
for(String forbidden: forbidden_words){
if(str.contains(forbidden)){ // o(mn)
containsForbidden = true;
break;
}
}
if(!containsForbidden)
filteredList.add(str);
}
String[] filteredArray = new String[filteredList.size()];
for(int i=0;i<filteredArray.length;i++){
filteredArray[i] = filteredList.get(i); //extra copying
}
return filteredArray;
}
I am assuming that "efficient" means something more than just a naive approach like most other answers including mine.
You can do two things to make it efficient:
Change your representation to a LinkedList instead of an array so that you can remove from an index without having to copy over to a new list/array.
Use KMP for String matching which is O(N) instead of String.contains() which is a naive implementation with O(MN) worst-case complexity.
Is it possible to copy and/or convert all values from String[] array into an ArrayList<BigInteger> in one just line?
Like this:
List<String> strings = Arrays.asList(StringArray);
My current source code had no problem but i'm finding a way (if there is) to make it more efficient.
List<BigInteger> Data = new ArrayList<BigInteger>();
for (String current : StringArray) //Gets values from array String[] unsorted
Data.add(new BigInteger(current)); //Each string will be added in the list
My logic to achieve my goal is to iterate through entire array of String[] then get each Strings and add every String into the List<BigInteger>
Use Streams:
List<BigInteger> data = Arrays.stream(StringArray).map(BigInteger::new).collect(Collectors.toList());
With Java 8 you could shortcut :
List<BigInteger> data = Arrays.stream(strings)
.map(BigInteger::new)
.collect(toList());
String [] TxtStr = new String[] {"bob","alan", "sam"};
List<String> stringList = new ArrayList<String>(Arrays.asList(TxtStr));
String [] TxtStr2 = new String[] {"bob","alan"};
List<String> stringList2 = new ArrayList<String>(Arrays.asList(TxtStr));
stringList.removeAll(stringList2);
String[] bTxtStr = stringList.toArray(new String[stringList.size()]);
String output = "nnn";
for (int x=0; x<bTxtStr.length; x++){
output +=bTxtStr[x];
}
Currently this is a small segment of an android project I'm working on where I have to compare the contents of 2 String[].
I've been having quite a few problems so I've started out with a simple case of 2 String[] with 2 and 3 elements respectively. After initializing the String[] I convert them to ArrayLists and perform the removeAll function, which ideally should remove the elements "bob" and "alan" from the first list and eventually the output.
BTW using remove to stringList.remove("bob") works in terms of eliminating that particular string from the ArrayList. Just wondering what I can do to ensure that stringList.removeAll(....) works.
Thanks for any help in advance.
you have bug in:
List<String> stringList2 = new ArrayList<String>(Arrays.asList(TxtStr));
you should use TxtStr2:
List<String> stringList2 = new ArrayList<String>(Arrays.asList(TxtStr2));
reomoveAll method of ArrayList definitely works fine. You have made mistake while creating second ArrayList.
For easy approach, you can use Java 8 Streams. Try the below code. It will give you directly single comma separated string. You can change separation character.
List<String> stringList = Arrays.asList("bob","alan", "sam");
List<String> stringList2 = Arrays.asList("bob","alan");
String mergedString = stringList.stream().filter(string ->!stringList2.contains(string)).collect(Collectors.joining(","));
System.out.println("Merged String: " + mergedString);
You might be ending up removing everything, because of your list creation which are based on same arrays. Change
List<String> stringList2 = new ArrayList<String>(Arrays.asList(TxtStr);
to
List<String> stringList2 = new ArrayList<String>(Arrays.asList(TxtStr2);
I know there is a String split method that returns an array but I need an ArrayList.
I am getting input from a textfield (a list of numbers; e.g. 2,6,9,5) and then splitting it at each comma:
String str = numbersTextField.getText();
String[] strParts = str.split(",");
Is there a way to do this with an ArrayList instead of an array?
You can create an ArrayList from the array via Arrays.asList:
ArrayList<String> parts = new ArrayList<>(
Arrays.asList(textField.getText().split(",")));
If you don't need it to specifically be an ArrayList, and can use any type of List, you can use the result of Arrays.asList directly (which will be a fixed-size list):
List<String> parts = Arrays.asList(textField.getText().split(","));
There is no such thing as a Split functionfor list, but you can do the split and then convert to a List
List myList = Arrays.asList(myString.split(","));