Concatenating elements of ArrayList while iterating - java

I am interested in concatenating a string to elements of an arraylist while iterating.When I run the below code,I am getting a ConcurrentModificationException.My code is:
ArrayList<String> list=new ArrayList<String>();
list.add("000);
list.add("00");
list.add("0");
for(String s:list)
{
if(s.length()==1)
{
String s2="000" + s;
list.add(s2);
}
if(s.length()==2)
{
String s2="00" + s;
}
if(s.length()==3)
{
String s2="0" + s;
}
}
My question is how to add the concatenated strings back to list without using StringBuilder as when I use a StringBuilder,it is causing other parts of my program to malfunction? So just need some guidance.

I would just use List.set:
List<String> list = new ArrayList<String>();
list.add("000");
list.add("00");
list.add("0");
for (int i = 0; i < list.size(); i++) {
String value = list.get(i);
list.set(i, ("0000" + value).substring(value.length()));
}

The exception will occur if you change the contents of the list (i.e. add or remove an element) anywhere in your for loop.
ArrayList<String> list=new ArrayList<String>();
list.add("000);
list.add("00");
list.add("0");
ArrayList<String> itemsToAdd = new ArrayList<String>(); // <======
for(String s:list) {
if(s.length()==1) {
String s2="000" + s;
//list.add(s2); DONT DO THIS
itemsToAdd.add(s2); // DO THIS INSTEAD
}
if(s.length()==2) {
String s2="00" + s;
}
if(s.length()==3) {
String s2="0" + s;
}
}
// NOW APPEND THE LIST
// This is safe as the iteration is complete.
list.addAll(itemsToAdd.add);

make a second list
add the new elements to that second list
add all the elements in the second list back into the first one after you're done iterating

Have a look at this one: Modifying Java ArrayList while iterating over it
Short story: Java won't let you change a list that you're iterating over. Instead, make a copy by putting the list to be cloned into the new arraylist's constructor arguments and then change the new list:
ArrayList<String> list=new ArrayList<String>();
list.add("000);
list.add("00");
list.add("0");
ArrayList<String> listSecond =new ArrayList<String>(list);
for(String s:list)
{
if(s.length()==1)
{
String s2="000" + s;
listSecond.add(s2);
}...

Your list.add(s2) is a problem. You just can't play with lists while iterating (well with an iterator you can delete items). Here's a possible solution:
ArrayList<String> list=new ArrayList<String>();
list.add("000");
list.add("00");
list.add("0");
List<String> newOnes = new ArrayList<>();
for(String s:list)
{
if(s.length()==1)
{
String s2="000" + s;
newOnes.add(s2);
}
if(s.length()==2)
{
String s2="00" + s;
}
if(s.length()==3)
{
String s2="0" + s;
}
}
list.addAll(newOnes);

create a tempList and add the element to tempList and at last assign tempList to list
public static void main (String[] args) throws Exception
{
ArrayList<String> list=new ArrayList<String>();
ArrayList<String> tempList=new ArrayList<String>();
list.add("000");
list.add("00");
list.add("0");
for(String s:list)
{
if(s.length()==1)
{
String s2="000" + s;
tempList.add(s2);
}
if(s.length()==2)
{
String s2="00" + s;
tempList.add(s2);
}
if(s.length()==3)
{
String s2="0" + s;
tempList.add(s2);
}
}
list=tempList;
System.out.println(list);
}

Modifying your list while iterating: (more generic and short)
ArrayList<String> list= new ArrayList<>();
String zeros = "00000000";
list.add("000");
list.add("00");
list.add("0");
for(int i=0;i<list.size();i++) {
String s = list.get(i) + zeros.substring(0,4-list.get(i).length());
list.set(i,s);
}
for (String s : list)
System.out.println(s);

Related

How to split strings of list into string array

I have a list that contains ("One.two.three", "one.two.four"). I want to save then in a string array as
One
two
three
one
two
four
What is the logic behind it?
You should be using java 8 to run this code. Just take those strings and split them on "."
split method of java need regex so to match "." you need "\.".Then transform array to list, then add words to list.
public static void main(String[] args) {
List<String> words = new ArrayList<String>();
List<String> list = new ArrayList<String>();
list.add("One.two.three");
list.add("one.two.four");
list.stream().forEach(str -> {
words.addAll(Arrays.asList(str.split("\\.")));
});
System.out.println(words.toString());
//output : [One, two, three, one, two, four]
}
For java 8+, you can use flatmap as -
String[] words = list.stream().flatMap(str -> Arrays.stream(str.split("\\."))).toArray(String[]::new);
If you are talking about the static arrays it is important to know array size to avoid "index is out of bounds" exception.
This way, I provide the solution that counts the number of words and then creates output s array to save every word.
We can use the String.split() function to get the single words we adding to output array:
String[] a = {"One.two.three", "one.two.four"};
int count = 0;
for (int i = 0; i < a.length; i++) { //skip this loop if you know the wanted array size
count += a[i].split("\\.").length;
}
String[] s = new String[count];
int k = 0;
for (int i = 0; i < a.length; i++) {
String[] b = a[i].split("\\.");
for (int j = 0; j < b.length; j++) {
s[k++] = b[j];
}
}
for (int i = 0; i < s.length; i++) {
System.out.println(s[i]);
}
Try this.
FOR JAVA 1.8+
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("One.two.three");
list.add("One.two.four");
List<String> newList = new ArrayList<String>();
list.forEach(string -> {
String[] stringArr = string.split("\\.");
for (String innerString : stringArr) {
newList.add(innerString);
}
});
String[] stringArr = newList.toArray(new String[newList.size()]);
System.out.println(Arrays.toString(stringArr));
}
UPTO JAVA 1.7
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("One.two.three");
list.add("One.two.four");
List<String> newList = new ArrayList<String>();
for (String string : list) {
String[] stringArr = string.split("\\.");
for (String innerString : stringArr) {
newList.add(innerString);
}
}
String[] stringArr = newList.toArray(new String[newList.size()]);
System.out.println(Arrays.toString(stringArr));
}
If you are below Java 8 you can use this snippet:
public class Main {
public static void main(String[] args) throws Exception {
List<String> originalList = new ArrayList();
List<String> finalList = new ArrayList();
originalList.add("One.two.three");
originalList.add("One.two.four");
for(String myString : originalList) {
//The \\ is to scape the dot
finalList.addAll(Arrays.asList(myString.split("\\.")));
}
//Creates an array from the list
String[] theArray = finalList.toArray(new String[finalList.size()]);
}
}
Finally, theArray will contain:
[One, two, three, one, two, four]
Take a look at the docs about splitting an string into parts

Modify elements of an ArrayList

For the below code, I was hoping that elements of my arraylist would be modified but its not. How can I modify the elements
public class Main {
public static void main(String args[]){
ArrayList<String> aList = new ArrayList<>();
aList .add("aa");
aList .add("bb");
aList .add("cc");
new Main().modifyList(aList );
for(String s: aList ){
System.out.println(s);
}
}
public void modifyList(ArrayList<String> aList ){
for(String s: aList){
System.out.println(s);
s = s + "ss";
}
}
}
Its printing
aa
bb
cc
aa
bb
cc
Expected output
aa
bb
cc
aass
bbss
ccss
public void modifyList(ArrayList<String> aList ){
for(String s: aList){
System.out.println(s);
s = s + "ss";
}
}
Strings are immutable. So when you change s you are creating a new object that is different than the one in the ArrayList.
So you need to iterate over the array and replace the old value with the new using the set method.
for (int i = 0; i < alist.size(); i++) {
String s = aList.get(i) + "ss";
aList.set(i, s);
}
To simply append the changes do the following:
int len = alist.size();
for (int i = 0; i < len; i++) {
String s = aList.get(i) + "ss";
aList.add(s);
}
Prints
aa bb cc aass bbss ccss
Here is the problem, the variable s is unused and visible only in the scope of the for-loop:
for (String s: aList) {
System.out.println(s);
s = s + "ss"; // the variable 's' is unused
}
Either use List::set to replace the current value:
for (int i=0; i<aList.size(); i++) {
String s = aList.get(i);
System.out.println(s);
aList.set(i, s + "ss");
}
... or use the advantage of java-stream as of java-8 and map the list to a new one:
List<String> newList = aList.stream()
.map(s -> s + "ss")
.collect(Collectors.toList());
s = s + "ss" only updates the local variable s, it doesn't update the list.
If you want to update elements in a list, use a ListIterator and the set() method:
public static void modifyList(List<String> aList) {
for (ListIterator<String> iter = aList.listIterator(); iter.hasNext(); ) {
String s = iter.next();
s = s + "ss";
iter.set(s); // replace element in the list with new value
}
}
In Java 8+, you can use a lambda expression with the replaceAll() method:
public static void modifyList(List<String> aList) {
aList.replaceAll(s -> s + "ss");
}
Both will perform well even if the list doesn't handle random access well, e.g. if the list is a LinkedList.
Test
public static void main(String[] args) {
List<String> aList = new ArrayList<>(Arrays.asList("aa", "bb", "cc"));
modifyList(aList);
System.out.println(aList);
}
Output
[aass, bbss, ccss]
In order to solve this, you need to update each element as follows:
public void modifyList(ArrayList<String> aList){
for(int i = 0; i < aList.size(); i++){
String s = aList.get(i);
aList.set(i, s+"ss");
}
}

Wil this work, how can i compare a string array elements to a predefined string and copy to a new array

Wil this work, how can i compare a string array elements to a predefined string and copy to a new array.
String element={"France","Germany","USA","France","Italy"}
String finalelement[]= null;
String compareelement = "France";
int l =elements.length;
int i1 = 0;
for(int i=0; i<l; i++)
{
//comparing the elements
if((compareelement.equals(element[i])))
{
//assigning the array element
finalelement[i1]=element[i];
i1++;
}
}
It's better to do it this way:
List<String> elements = new ArrayList<>();
elements.add("France");
elements.add("Germany");
elements.add("USA");
elements.add("France");
elements.add("Italy");
List<String> finalElement = new ArrayList<>();
String compareElement = "France";
for (String str : elements) {
if (compareElement.equals(str)) {
finalElement.add(str);
}
}
At least the first line is wrong:
String element={"France","Germany","USA","France","Italy"}
String[] elements = new String[]{"France","Germany","USA","France","Italy"}

How can I combine elements at the same index from separate lists?

I am trying to combine multiple String lists.
Say I have two (could be more) lists of the same size:
List<String> list1 = Arrays.asList("1One","1Two","1Three");
List<String> list2 = Arrays.asList("2One","2Two","2Three");
I want to combine the value of the corresponding indexes and place them into a new list:
List3 = new {"1One2One", "1Two2Two", "1Three2Three"};
Currently I have a list of 2 objects, each object contains the list that I want to combine the elements within.
So I want to combine element 1 in the list from object 1 with element 1 from the list from object 2.
This is what I have attempted:
public void generateFileList(List<Object> cl){
int count = 0;
String temp = "";
for(int i = 0; i < cl.size(); i++){
for (int x = 0; x < cl.get(i).getItemList().size(); x++) {
if (count == x){
temp += cl.get(i).getListItem(x);
break;
}
}
count++;
textList.add(temp);
}
}
public void test(){
for(String s : textList){
System.out.println("List Element - " + s);
}
System.out.println(textList.size());
}
Which prints out:
List Element - 1One
List Element - 1One1Three
What am I doing wrong here?
First, the code you have won't compile. It should be:
List<String> list1 = Arrays.asList("1One","1Two","1Three");
List<String> list2 = Arrays.asList("2One","2Two","2Three");
Next, it is best to use an Iterator than access a List by index:
public List<String> concat(final List<String> list1, final List<String> list2) {
final Iterator<String> i1 = list1.iterator();
final Iterator<String> i2 = list2.iterator();
final List<String> combined = new ArrayList<>();
while (i1.hasNext() && i2.hasNext()) {
combined.add(i1.next() + i2.next());
}
return combined;
}
For an arbitrary number of List:
public List<String> concat(final List<String>... lists) {
final List<Iterator<String>> it = new LinkedList<>();
for (List<String> l : lists) {
it.add(l.iterator());
}
final List<String> combined = new ArrayList<>();
outer:
while (true) {
final StringBuilder sb = new StringBuilder();
for (final Iterator<String> i : it) {
if (!i.hasNext()) {
break outer;
}
sb.append(i.next());
}
combined.add(sb.toString());
}
for (final Iterator<String> i : it) {
if (i.hasNext()) {
throw new IllegalArgumentException("Lists not the same length.");
}
}
return combined;
}
If the lists have the same size, just have a for loop from 0 to list size, and add in the new list the concatenation of the elements from the same position in the two lists, like for (int i =0; i< list1.size(); i++) { resultedlist.add(list1.get(i) + list2.get(i))}
Presuming the 2 lists are the same size:
List<String> list1 = new {"1One","1Two","1Three"};
List<String> list2 = new {"2One","2Two","2Three"};
List<String> list3 = new ArrayList<>();
for (int i = 0; i < list1.size(); i++) {
list3.add(list1.get(i) + list2.get(i));
}

How do i return an ArrayList<String> from a method?

Here is my first method. I have a file that I added its contents to an ArrayList. I can print that just fine but I need to create a method that adds line numbers to the beginning of each String. I can do that outside the method but i'm having problems creating a method that returns an arrayList so i can use the updated arrayList in other methods and then I need to display the updated ArrayList. Here is my code.
My output for the first method should be
1 bird
2 cat
etc...
My output for the second method should return the elements in the ArrayList in reverse order.
2 cat
1 bird
etc...
import java.util.*;
import java.io.*;
public class List
{
public static void main(String[] args) throws IOException
{
int line =1;
ArrayList<String> textArray = new ArrayList<String>();
ArrayList<String> newArray = new ArrayList<String>();
File f = new File("src/List.txt");
Scanner sc = new Scanner(f);
int num = 1;
while(sc.hasNext())
{
textArray.add(sc.nextLine());
}
numbered(textArray);
reverseOrder(textArray);
}
public static ArrayList<String> numbered(ArrayList<String> textArray)
{
ArrayList<String> results = new ArrayList<String>(textArray.size());
String s;
int num = 1;
for (String r : results)
{
r = num + " " + results;
num++;
}
return results;
}
public static ArrayList<String> reverseOrder(ArrayList<String> textArray)
{
ArrayList<String> results = new ArrayList<String>(textArray.size());
String s;
int num = 1;
for (String r : results)
{
}
return results;
}
You are returning your arrays correctly, the problem is that you are creating new Objects inside your methods, instead of using the ones you receive as parameters
ArrayList<String> results = new ArrayList<String>(textArray.size());
So you are iterating empty arrays.
Inside your for loop, you could just iterate the received ArrayList
for (String r : textArray)
Also, your results array is always empty, you should add new elements like this:
results.add(r);
This may work:
public static ArrayList<String> numbered(ArrayList<String> textArray)
{
ArrayList<String> results = new ArrayList<String>(textArray.size());
String s;
int num = 1;
for (String r : textArray)
{
r = num + " " + results;
num++;
results.add(r);
}
return results;
}
Have not tested this but it should work. As you can see pretty straight forward. Best of Luck and happy coding.
public ArrayList<String> numList(ArrayList<String> originalArrayList)
{
ArrayList<String> newNumberedList = new ArrayList<String>();
for(int i = 0;i< originalArrayList.size(); i++){
int newi = i+1;
newNumberedList.add(newi+". "+originalArrayList.get(i));
}
return newNumberedList ;
}
You are instantiating the 'results' arraylist, and iterating it. You need to iterate the textArray list for starters and call results.add("text");

Categories

Resources