Removing element in ArrayList using INDEX causing java.util.ConcurrentModificationException - java

The following code is causing
java.util.ConcurrentModificationException
I am not sure how to solve the error please help !
ArrayList strList = new ArrayList<String>(Arrays.asList(cmd.split(" ")));
if (strList.get(0).equals("LIST")) {
}
if (strList.get(0).equals("DEPEND")) {
strList.remove(0); // getting error at this point
cm.createComponent(strList);
}
Full Method The outer loop is not related to the List
public static void main(String[] args) throws IOException {
ComponentManager cm = new ComponentManager();
List<String> lines = Files.readAllLines(Paths.get("cmdList.txt"));
for (String cmd : lines) {
ArrayList strList = new ArrayList<String>(Arrays.asList(cmd.split(" ")));
if (strList.get(0).equals("LIST")) {
}
if (strList.get(0).equals("DEPEND")) {
strList.remove(0);
cm.createComponent(strList);
}
if (strList.get(0).equals("INSTALL")) {
}
if (strList.get(0).equals("REMOVE")) {
}
}
}

You can create a different ArrayList and perform remove operation there or put up an iterator on the arrayList and remove using the iterator.
Find a couple of potential solutions to your problem here and here.

Related

Not able to access individual element from sublist

I am a beginner in java. I want to read elements one by one in sublist.
public class ListFirst {
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
List<List<Integer>>bigList= new ArrayList<>();
// I want to access an element of bigList one by one. how to do that?
}
}
If there is no sublist I can print using for loop upto list.size() and list.get() to print but here element is list itself..so I dont know how to read. could you please help me with that.
I modified your code to achieve what you wanted to do:
public class ListFirst {
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
List<List<Integer>>bigList= new ArrayList<>();
bigList.add(list1);
bigList.add(list2);
for (List<Integer> list : bigList) {
for (Integer i : list) {
System.out.print(i.intValue() + " ");
}
}
}
}
An alternative would be to not use nested List for storing your Integers:
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
// bigList is a list of Integers not list of lists
List<Integer>bigList= new ArrayList<>();
bigList.addAll(list1); // add all elements from list1
bigList.addAll(list2); // add all elements from list2
for (Integer i : bigList) {
System.out.print(i.intValue() + " ");
}
}
Assuming that the lists have bee added to bigList, you can iterate it using the for-each loop as shown below:
bigList.add(list1);
bigList.add(list2);
for (List<Integer> list : bigList) {
System.out.println(list);
}
DEMO
Using the traditional loop, you can print bigList as shown below:
for (int i = 0; i < bigList.size(); i++) {
System.out.println(bigList.get(i));
}
You can do the following:
bigList.stream()
.flatMap(Collection::stream)
.forEach(x -> System.out.println(x));
Output:
10
20
30
40
100
200
300
400

Iterating through sets

I am writing a program that will receive a list of words. After that, it will store the repeated words and the non repeated into two different lists. My code is the following:
public class Runner
{
public static void run (Set<String> words)
{
Set<String> uniques= new HashSet<String>();
Set<String> dupes= new HashSet<String>();
Iterator<String> w = words.iterator();
while (w.hasNext())
{
if (!(uniques.add(w.next())))
{
dupes.add(w.next());
}
else
{
uniques.add(w.next());
}
}
System.out.println ("Uniques: "+ uniques);
System.out.println ("Dupes: "+ dupes);
}
}
However, the output for the following:
right, left, up, left, down
is:
Uniques: [left, right, up, down]
Dupes: []
and my desired would be:
Uniques: [right, left, up, down]
Dupes: [ left ]
I want to achieve this using sets. I know it would be way easier to just an ArrayList but I am trying to understand sets.
The reason for your problem is that the argument words is a Set<String>. A set by definition will not contain duplicates. The argument words should be a List<String>. The code also makes the mistake of calling w.next() twice. A call to the next() will cause the iterator to advance.
public static void run(List<String> words) {
Set<String> uniques= new HashSet<String>();
Set<String> dupes= new HashSet<String>();
Iterator<String> w = words.iterator();
while(w.hasNext()) {
String word = w.next();
if(!uniques.add(word)) {
dupes.add(word);
}
}
}
You are doing uniques.add(w.next()) twice. Why?
Also, don't keep calling w.next() - this makes the iteration happen. Call it once and keep a local reference.
Use:
String next = w.next();
if(uniques.contains(next)) {
// it's a dupe
} else {
// it's not a dupe
}

Java ArrayList<String> .contains() in hadoop

I am trying to remove the duplicated strings in an ArrayList called outputList in Hadoop.
Here is my code:
List<String> newList = new ArrayList<String>();
for( String item : outputList){
if(!newList.contains(item))
newList.add(item);
else newList.add("wrong");
}
The problems is that the strings in newList are all "wrong".
Some facts:
1. The above code works well at local machine.
I can write out the strings in outputList in hadoop. Most strings in outputList are different (duplicates exist).
I tried some other method to remove duplicated items. Like using HashSet. But when I use outputList to initialize a HashSet, the obtained HashSet is empty.
The java version in Hadoop is javac 1.6.0_18
Thanks.
The following is my reducer code:
public static class EditReducer
extends Reducer<Text,Text,Text,Text> {
private Text editor2 = new Text();
public void reduce(Text key, Iterable<Text> values,
Context context
) throws IOException, InterruptedException {
//write the content of iterable to an array list.
List<String> editorList =new ArrayList<String>();
for (Text t:values) {
editorList.add(t.toString());
}
//if a user appears more than once in the list, add to outputList
int occ;
List<String> outputList =new ArrayList<String>();
for (int i=0;i<editorList.size();i++) {
occ= Collections.frequency(editorList, editorList.get(i));
if(occ>1) {
outputList.add(editorList.get(i));
}
}
//make outputList distinct
List<String> newList = new ArrayList<String>();
for( String item : outputList){
if(!newList.contains(item))
newList.add(item);
else newList.add("wrong");
}
for (String val : newList) {
editor2.set(val);
context.write(editor2,editor2);
}
}
}
You can create a nested for loop inside your original for loop and compare the strings that way:
List<String> newList = new ArrayList<String>();
for(String item : outputList) {
boolean contains = false;
for(String str: newList) {
if(str.equals(item)) {
contains = true;
break;
}
}
if(!contains) {
newList.add(item);
}
else {
newList.add("wrong");
}
}

List<String> minus List<String>

I have following code. In the first i tried to set values in the list called 'unavailable'.
Next, in the for each I have to produce a cycle on the list domainStr minus unavailable. How can i do it?
public Result execute(List<String> domainsStr) {
Result result = new Result();
try {
List<String> domains = domainService.findByNames(domainsStr);
result.setUnavailable(domains);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
for (String domain : domainsStr) {
......
}
return result;
}
public static class Result {
private List<String> unavailable = new ArrayList<>();
public List<String> getUnavailable() {
return unavailable;
}
public void setUnavailable(List<String> unavailable) {
this.unavailable = unavailable;
}
}
removeAll(Collection c) is the function which would be the most helpful to you. Having said that, this will work properly only if you have the equals method correctly defined for your Domain object. In this case it is a String so it doesnt matter. But, just to keep it in mind.
so just say, domainsStr.removeAll(result.getUnavailable());
Also, if the Result class is static, why the new object creation here?
Result result = new Result();
This result.setUnavailable(domains);
can be changed to
Result.setUnavailable(domains);
I have to to produce a cycle on the list domainStr minus unavailable.
If I understood correctly, I think you are looking for the removeAll method :
Removes from this list all of its elements that are contained in the
specified collection (optional operation).
domainsStr.removeAll(result.getUnavailable());
for (String domain : domainsStr) {
}
If you want to let domainsStr unchanged, you can create a temporary list and perfom these operations on it.
List<String> tempList = new ArrayList<String>(domainsStr);
tempList.removeAll(result.getUnavailable());
for(String domain : tempList){
.....
I put them into a tempt list so you don't lose the items in the domainsStr list.

Using a returned ArrayList

I'm currently desperatly trying to get an ArrayList that I return from a function into a new ArrayList in my main function...
Here are the code snippets:
public static ArrayList<String> permute(String begin, String end) {
ArrayList<String> al=new ArrayList<String>();
//filling bla
return al;
}
and here's where I call the function in the main function:
ArrayList<String> arr =permute("","abc");
arr unfortunately is empty, and I have no idea how to get it to work :(
Thanks in advance
EDIT:
Here's the full code:
import java.util.*;
class Problem24 {
public static ArrayList<String> permute(String begin, String end) {
ArrayList<String> al=new ArrayList<String>();
if (end.length() <= 1) {
String s=begin+end;
al.add(s);
} else {
for (int i = 0; i < end.length(); i++) {
try {
String newString = end.substring(0, i) + end.substring(i + 1);
permute(begin + end.charAt(i), newString);
} catch (StringIndexOutOfBoundsException exception) {
exception.printStackTrace();
}
}
}
return al;
}
public static void main (String[] args)
{
ArrayList<String> arr =permute("","abc");
System.out.println(arr.get(0));
}
}
Your ArrayList is empty but not null which means that the returning part worked. In oder to use the values from the method you need to fill the ArrayList inside the method.
ps: You should use List list = new ArrayList() or
List list = permute("", "abc") which is a simple version of dependency injection and a better design of your program.
You're not adding the items from the recursive calls.
Try adding the al.addAll to your permute call:
al.addAll(permute(begin + end.charAt(i), newString));
before returning the value make sure you are filling the al List
al.add(begin);
al.add(end);
al.add("any other string");
return al;
Obviously something in wrong with the // filling bla part.
I'd start with replacing your code in // filling bla with al.add("TEST"); and see if you even get something out.
Also your method is static and the source array isn't passed in, which suggest that either your code is supposed to permute those strings somehow. Are you possibly acting upon a static array (i.e. permute all elements between begin and end), and the source array is empty?
import java.util.*;
class Problem24
{
public static ArrayList<String> permute(String begin, String end)
{
ArrayList<String> al=new ArrayList<String>();
if (endingString.length() <= 1)
{
String s=begin+end;
al.add(s);
}
else
{
for (int i = 0; i < end.length(); i++)
{
try
{
String newString = end.substring(0, i) + end.substring(i + 1);
al.add(permute(begin + end.charAt(i), newString));
}
catch (StringIndexOutOfBoundsException exception)
{
exception.printStackTrace();
}
}
}
return al;
}
public static void main (String[] args)
{
ArrayList<String> arr = permute("","abc");
System.out.println(arr.get(0));
}
}
hope i corrected it the right way.
You call your method permute recurrently --- but you make no use of what it returns when it returns. In other words, you create a new array each time you call permute, but everything you get in for-loop is lost, as you are not passing it to next permute() calls --- eventually you return an empty array in which you didn't put anything.

Categories

Resources