ConcurrentModificationException when I acces to list of list without modifying - java

When I acces to list of list with this function,It make ConcurrentModificationException in second for loop but i don't understand why this Exception is triggered .
public static List<List<Dico>> weight_term(List<List<Dico>> sublists ,List<String> sinificativ )
{
List<List<Dico>> matrix_node_term = new ArrayList<>();
List<Dico> list_node = new ArrayList<>();// a new list for node
for (List<Dico> sublist : sublists) // to get each sublist List<Dico>
{
for (Dico dico : sublist) // get each Dico in the sublist -->ConcurrentModificationException
{
String term =dico.getTerm();
int id = dico.getDocId();
if(sinificativ.contains(term)) // if this term exist in sinificativ erm list
{
list_node.add(dico); // it add to list_node
}
else
{
list_node.add(new Dico(id,term,0.0)); // it add to list_node with null weigth
}
}
matrix_node_term.add(list_node); // add each list to list of list
}
return matrix_node_term;
}
The dico class is used to store term,id of document and the weight of this term in that document :
public class Dico implements Comparable
{
private final String m_term;
private double m_weight;
private final int m_Id_doc;
public Dico(int Id_Doc,String Term,double tf_ief )
{
this.m_Id_doc = Id_Doc;
this.m_term = Term;
this.m_weight = tf_ief;
}
}
This Exception is triggered without any modification in the sutucte of list or its elements .

Probleme comes from a function used to split List in multiple List:
List<List<Dico>> sublists = new ArrayList<>(change);
for (int i = 0; i < change; i++)
{
sublists.add(list.subList(changes[i],changes[i + 1]));
}
A solution comes from pbabcdefp
List<List<Dico>> sublists = new ArrayList<>(change);
for (int i = 0; i < change; i++)
{
sublists.add(newArrayList<Dico>(list.subList(changes[i], changes[i + 1])));
}
thank you for your help

Related

how to Add ArrayList in ArrayList

I got a problem when insert an ArrayList into ArrayList.
My source code:
import java.util.ArrayList;
public class Ask {
public static void main(String[] args) {
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
ArrayList<ArrayList<String>> result =new ArrayList<ArrayList<String>>();
result.add(mentah);
}
}
How can I create a list based on that data; that will look like:
[[data1,data2,data3],[data4,data5,data6],[data7,data8,data9,data10]]
10 div 3 is 3 (so 3 elements per sublist)
10 mod 3 is 1 (so last sublist has 4 entries)
10 divide by 3 is
3 3 4
Just upgraded the answer of #Narayana Ganesh:
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> result = new ArrayList<List<String>>();
for (int j= 0; j< mentah.size() ; j+=3) {
int end = mentah.size() <= j+2 ? mentah.size() : j+3;
if(mentah.size() - j == 4) end = end +1;
if(j != 9) result.add(mentah.subList(j, end));
}
System.out.println(result);
}
Result:
[[Reza, Fata, Faldy], [Helsan, Dimas, Mamun], [Erik, Babeh, Tio, Mamang]]
A more generic solution would look like:
List<String> allNames = Arrays.asList("Reza", "Fata", ...
List<List<String>> slicedNames = new ArrayList<>();
List<String> sublist = new ArrayList<>();
int sublistTargetLength = 3;
for (String name : allNames) {
sublist.add(name);
if (sublist.size() == sublistTargetLength) {
slicedNames.add(sublist);
sublist = new ArrayList<>();
}
}
if (sublist.size() > 0) {
slicedNames.get(slicedNames.size()-1).addAll(sublist);
}
Some notes:
The above iterates your initial list of names (which can created using that single call to Arrays.asList()); and puts the entries into same-sized lists; which are then added to the slicedNames list of list.
If there is any "remaining" data; that is simply added to the last element of the list of list.
You should prefer to use the interface type List for your variable types; you only use the specific implementation class (ArrayList) when instantiating the list
When iterating anything, prefer the for-each looping style when possible
Try this. You can achieve this using subList method.
import java.util.ArrayList;
import java.util.List;
public class Ask {
public static void main(String[] args) {
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> result = new ArrayList<List<String>>();
for (int j= 0; j< mentah.size() ; j+=3) {
int end = mentah.size() <= j+2 ? mentah.size() : j+3;
result.add(mentah.subList(j, end));
}
for (List<String> item : result) {
System.out.println(" - -"+item);
}
}
}
First create sublists with a maximal size of 3 which will give you something like this
[[Reza, Fata, Faldy], [Helsan, Dimas, Mamun], [Erik, Babeh, Tio], [Mamang]]
then check if the last sublist size is less than 3 if yes add this to the second last sublist and remove the last one
public class Example {
public static void main(String[] args) {
List<String> mentah = new ArrayList<>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> parts = new ArrayList<>();
int sizeOfOriginalList = mentah.size();
int sizeOfSubLists = 3;
for (int i = 0; i < sizeOfOriginalList; i += sizeOfSubLists) {
parts.add(new ArrayList<>(mentah.subList(i, Math.min(sizeOfOriginalList, i + sizeOfSubLists))));
}
if(parts.get(parts.size()-1).size()<sizeOfSubLists){
parts.get(parts.size()-2).addAll(parts.get(parts.size()-1));
parts.remove(parts.get(parts.size()-1));
}
System.out.println(parts);
}
}

How to create combinations of values in Java?

I have the following map: Map<Integer,String[]> map = new HashMap<Integer,String[]>();
The keys are integers and the values are arrays (could also be replaced by lists).
Now, I would like to get all possible combinations of the values among the keys. For example, let's say the map contains the following entries:
key 1: "test1", "stackoverflow"
key 2: "test2", "wow"
key 3: "new"
The combinations consists of
("test1","test2","new")
("test1","wow","new")
("stackoverflow", "test2", "new")
("stackoverflow", "wow", "new")
For this I imagine a method boolean hasNext() which returns true if there is a next pair and a second method which just returns the next set of values (if any).
How can this be done? The map could also be replaced by an other data structure.
The algorithm is essentially almost the same as the increment algorithm for decimal numbers ("x -> x+1").
Here the iterator class:
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.TreeSet;
public class CombinationsIterator implements Iterator<String[]> {
// Immutable fields
private final int combinationLength;
private final String[][] values;
private final int[] maxIndexes;
// Mutable fields
private final int[] currentIndexes;
private boolean hasNext;
public CombinationsIterator(final Map<Integer,String[]> map) {
combinationLength = map.size();
values = new String[combinationLength][];
maxIndexes = new int[combinationLength];
currentIndexes = new int[combinationLength];
if (combinationLength == 0) {
hasNext = false;
return;
}
hasNext = true;
// Reorganize the map to array.
// Map is not actually needed and would unnecessarily complicate the algorithm.
int valuesIndex = 0;
for (final int key : new TreeSet<>(map.keySet())) {
values[valuesIndex++] = map.get(key);
}
// Fill in the arrays of max indexes and current indexes.
for (int i = 0; i < combinationLength; ++i) {
if (values[i].length == 0) {
// Set hasNext to false if at least one of the value-arrays is empty.
// Stop the loop as the behavior of the iterator is already defined in this case:
// the iterator will just return no combinations.
hasNext = false;
return;
}
maxIndexes[i] = values[i].length - 1;
currentIndexes[i] = 0;
}
}
#Override
public boolean hasNext() {
return hasNext;
}
#Override
public String[] next() {
if (!hasNext) {
throw new NoSuchElementException("No more combinations are available");
}
final String[] combination = getCombinationByCurrentIndexes();
nextIndexesCombination();
return combination;
}
private String[] getCombinationByCurrentIndexes() {
final String[] combination = new String[combinationLength];
for (int i = 0; i < combinationLength; ++i) {
combination[i] = values[i][currentIndexes[i]];
}
return combination;
}
private void nextIndexesCombination() {
// A slightly modified "increment number by one" algorithm.
// This loop seems more natural, but it would return combinations in a different order than in your example:
// for (int i = 0; i < combinationLength; ++i) {
// This loop returns combinations in the order which matches your example:
for (int i = combinationLength - 1; i >= 0; --i) {
if (currentIndexes[i] < maxIndexes[i]) {
// Increment the current index
++currentIndexes[i];
return;
} else {
// Current index at max:
// reset it to zero and "carry" to the next index
currentIndexes[i] = 0;
}
}
// If we are here, then all current indexes are at max, and there are no more combinations
hasNext = false;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Remove operation is not supported");
}
}
Here the sample usage:
final Map<Integer,String[]> map = new HashMap<Integer,String[]>();
map.put(1, new String[]{"test1", "stackoverflow"});
map.put(2, new String[]{"test2", "wow"});
map.put(3, new String[]{"new"});
final CombinationsIterator iterator = new CombinationsIterator(map);
while (iterator.hasNext()) {
System.out.println(
org.apache.commons.lang3.ArrayUtils.toString(iterator.next())
);
}
It prints exactly what's specified in your example.
P.S. The map is actually not needed; it could be replaced by a simple array of arrays (or list of lists). The constructor would then get a bit simpler:
public CombinationsIterator(final String[][] array) {
combinationLength = array.length;
values = array;
// ...
// Reorganize the map to array - THIS CAN BE REMOVED.
I took this as a challenge to see whether the new Java 8 APIs help with these kind of problems. So here's my solution for the problem:
public class CombinatorIterator implements Iterator<Collection<String>> {
private final String[][] arrays;
private final int[] indices;
private final int total;
private int counter;
public CombinatorIterator(Collection<String[]> input) {
arrays = input.toArray(new String[input.size()][]);
indices = new int[arrays.length];
total = Arrays.stream(arrays).mapToInt(arr -> arr.length)
.reduce((x, y) -> x * y).orElse(0);
counter = 0;
}
#Override
public boolean hasNext() {
return counter < total;
}
#Override
public Collection<String> next() {
List<String> nextValue = IntStream.range(0, arrays.length)
.mapToObj(i -> arrays[i][indices[i]]).collect(Collectors.toList());
//rolling carry over the indices
for (int j = 0;
j < arrays.length && ++indices[j] == arrays[j].length; j++) {
indices[j] = 0;
}
counter++;
return nextValue;
}
}
Note that I don't use a map as an input as the map keys actually don't play any role here. You can use map.values() though to pass in the input for the iterator. With the following test code:
List<String[]> input = Arrays.asList(
new String[] {"such", "nice", "question"},
new String[] {"much", "iterator"},
new String[] {"very", "wow"}
);
Iterator<Collection<String>> it = new CombinatorIterator(input);
it.forEachRemaining(System.out::println);
the output will be:
[such, much, very]
[nice, much, very]
[question, much, very]
[such, iterator, very]
[nice, iterator, very]
[question, iterator, very]
[such, much, wow]
[nice, much, wow]
[question, much, wow]
[such, iterator, wow]
[nice, iterator, wow]
[question, iterator, wow]

Find all combinations of an ArrayList of ArrayLists of user defined objects

I have defined a class Note that represents a way to play a certain note (two integers for the string and fret on a string instrument), and a class Chord which has an ArrayList of all the notes in that chord.
For every note that is played there may be multiple ways of playing that note so I have an ArrayList of Notes representing each possible way. In a chord there can be any number of notes so I have an ArrayList of ArrayLists of Notes. From this I want to create an ArrayList of chords with each possible way of playing the chord.
I have defined a constructor Chord(ArrayList<Note> notes)
eg:
Note A has 3 ways of being played and note B 2 ways of being played, from this I would want chords with:
[A1,B1], [A1,B2], [A2 B1], [A2 B2], [A3,B1], [A3,B2].
I have created a method that works under the assumption that there are always 3 notes played but can't think how to expand it to work for an unknown number
public static ArrayList<Chord> allPlayable(ArrayList<ArrayList<Note>> candidates)
{
ArrayList<Chord> allPlayable = new ArrayList<>();
for (int i = 0; i < candidates.get(0).size(); i++)
{
Note n0 = candidates.get(0).get(i);
for (int j = 0; j < candidates.get(1).size(); j++)
{
Note n1 = candidates.get(1).get(j);
for (int k = 0; k < candidates.get(2).size(); k++)
{
Note n2 = candidates.get(1).get(k);
ArrayList<Note> chordNotes = new ArrayList<>();
chordNotes.add(n0);
chordNotes.add(n1);
chordNotes.add(n2);
allPlayable.add(new Chord(chordNotes));
}
}
}
return allPlayable;
}
IT was suggested to me to use recursion - every for loop would be another recursive call and I came up with this answer
public static ArrayList<Chord> allPlayable(ArrayList<ArrayList<Note>> candidates)
{
//this will be the inner ArrayList we are on
ArrayList<Note> current = new ArrayList();
//the list of chords to return
ArrayList<Chord> allPlayable = new ArrayList();
allPlayableRecurse(candidates, 0, current, allPlayable);
return allPlayable;
}
public static void allPlayableRecurse(ArrayList<ArrayList<Note>> candidates, int index, ArrayList<Note> chordNotes, ArrayList<Chord> allPlayable)
{
ArrayList<Note> current = candidates.get(index);
//for each note in the current array list of notes
for (int i = 0; i < current.size(); i++)
{
chordNotes.add(current.get(i));
//there are more notes to add
if (index < candidates.size()-1)
{
//go to the next inner ArrayList
allPlayableRecurse(candidates, index+1, chordNotes, allPlayable);
}
else//we have reached the last note
{
//add the chord to the list
allPlayable.add(new Chord((ArrayList<Note>)chordNotes.clone()));
}
//we will now replace this note
chordNotes.remove(chordNotes.size()-1);
}
}
You could use recursion, for example:
List<List<Note>> combine(List<List<Note>> representations) {
List<Note> options = representations.get(0);
List<List<Note>> tails;
if (representations.size()==1) {
tails = new ArrayList<>();
tails.add(Collections.emptyList());
} else {
tails = combine(representations.subList(1, representations.size()));
}
List<List<Note>> combinations = new ArrayList<>(options.size());
for (Note note : options) {
for (List<Note> tail : tails) {
List<Note> chord = new ArrayList<>();
chord.add(note);
chord.addAll(tail);
combinations.add(chord);
}
}
return combinations;
}
public List<Chord> allPlayable(List<List<Note>> candidates) {
List<List<Note>> combinations = combine(candidates);
List<Chord> chords = new ArrayList<>(combinations.size());
for (List<Note> notes : combinations) chords.add(new Chord(notes));
return chords;
}
It is the old java7 style. It can be done easier with new Java8 functional operations but not sure if it is already your thing if you just started.

how to iterate through an array list of class type

I have two classes A and B. I want to access an array list in A from B. The array list is of class C type, which stores objects(packets). I would like to know if there is any way to iterate through the list and get specific data from each packet.
public class PcapStream
{
PcapParser objPcapParser = new PcapParser();
PcapDef numPackets = new PcapDef();
int listSize = numPackets.getMaxPackets();
public void findStream()
{
final ListIterator<PcapDef> packetIterator = objPcapParser.packet_list.listIterator();
while(packetIterator.hasNext())
{
for(final int i=0; i<=listSize;i++)
{
I started off with something like this. Not sure how it works. Class B is PcapStream, Class A is PcapParser, Class C is PcapDef
ListIterator packetIterator = objPcapParser.packet_list.listIterator();
while(packetIterator.hasNext())
{
for(int i=0; i<listSize; i++ )
{
PcapDef packet1 = (PcapDef) packetIterator.next();
PcapDef packet2 = packetIterator; //here I would like to get the 2nd object from the list, not sure how to get that at this point.
}
}
public int compare(final PcapDef packet1, final PcapDef packet2)
{
return 0;
}
I'm still working on it. At this point this is what I have
public void findStream()
{
try
{
for(int i=0;i<listSize;i++)
{
final List <PcapDef> list = new ArrayList<PcapDef>();
final PcapDef packet1 = objPcapParser.packet_list.get(i);
checkPackets(packet1, list, i);
}
}
catch(final IndexOutOfBoundsException e)
{
System.out.println("Exception : " + e);
}
final Set packetSet = Stream.entrySet();
final Iterator setIterator = packetSet.iterator();
while(setIterator.hasNext())
{
final Map.Entry packetEntry = (Map.Entry) setIterator.next();
System.out.print(packetEntry.getKey() + ": ");
System.out.println(packetEntry.getValue());
}
}
private void checkPackets(final PcapDef packet1, final List<PcapDef> list, final int i)
{
for(int j=1;j<listSize && j!=i;j++)
{
final PcapDef packet2 = objPcapParser.packet_list.get(j);
final int value = compare(packet1,packet2);
if(value == 0)
{
list.add(packet1);
list.add(packet2);
checkPackets(packet2, list, i);
}
else
{
Stream.put(i,list); //add list to hashmap
}
}
}
#Override
public int compare(final PcapDef packet1, final PcapDef packet2)
{
final String header1 = packet1.getHeader();
final String header2 = packet2.getHeader();
final String src_port1 = packet1.getSrc_port();
final String dst_port2 = packet2.getDst_port();
final String src_port2 = packet2.getSrc_port();
final String dst_port1 = packet1.getDst_port();
System.out.println(header1 + header2);
int flag = 1;
try{
if(header1.equalsIgnoreCase(header2))
{
if((src_port1.substring(10).equalsIgnoreCase(dst_port2.substring(10))) && (src_port2.substring(10).equalsIgnoreCase(dst_port1.substring(10)) )
{
flag = 0;
return flag;
}
}
}
#Andy This is what I wrote so far. Problems I'm facing: Duplicates are being generated and hashmap entries are not continuous, I mean like index 0,1,2.. instead few locations are empty. Due to this if I give very large files as input to my program it is throwing me an indexoutofboundsexception. I'm a beginner and trying my best. Kindly, help.
You can use the Iterator.next() method to get the next list member. Each call to next() advances to the next list member.
while(packetIterator.hasNext())
{
PCapDef packet = packetIterator.next();
...
}
EDIT:
And you can use the Iterator.get(int) method to get a list member by index.
while(packetIterator.hasNext())
{
PCapDef packet = packetIterator.next();
for(int i=0; i<listSize; i++ )
{
PcapDef packet2 = objPcapParser.packet_list.get( i )
...
}
}

Get value (String) of ArrayList<ArrayList<String>>(); in Java

I know it's simple question, but in
ArrayList<ArrayList<String>> collection;
ArrayList<String> listOfSomething;
collection= new ArrayList<ArrayList<String>>();
listOfSomething = new ArrayList<String>();
listOfSomething.Add("first");
listOfSomething.Add("second");
collection.Add(listOfSomething);
listOfSomething.Clear();
listOfSomething.Add("first");
collection.Add(listOfSomething);
I want to take String from ArrayList of ArrayList, and I don't know how to do that. For example I go
ArrayList<String> myList = collection.get(0);
String s = myList.get(0);
and it works! but:
Big update:
private List<S> valuesS;
private List<Z> valuesZ;
ArrayList<ArrayList<String>> listOfS;
ArrayList<String> listOfZ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Zdatasource = new ZDataSource(this);
Zdatasource.open();
valuesZ = Zdatasource.getAllZ();
Sdatasource = new SDataSource(this);
Sdatasource.open();
valuesS = Sdatasource.getAllS();
List<Map<String, String>> groupData
= new ArrayList<Map<String, String>>();
List<List<Map<String, String>>> childData
= new ArrayList<List<Map<String, String>>>();
listOfS = new ArrayList<ArrayList<String>>();
listOfZ = new ArrayList<String>();
for (S i : valuesS) { // S is class
for (Z j : valuesZ) { // Z is class
if(j.getNumerS().equals(i.getNumerS())) {
listOfZ.add(j.getNumerZ());
}
else
{
//listOfZ.add("nothing");
}
}
listOfS.add(listOfZ);
if(!listOf.isEmpty()) listOfZ.clear();
}
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
try
{
ArrayList<String> myList = listOfS.get(groupPosition);
String s = myList.get(childPosition);
PrintToast("group "+Integer.toString(groupPosition)+", child "+Integer.toString(childPosition) + " , "+ s);
}
catch(Exception e)
{
Log.e("FS", e.toString());
}
return true;
}
return me java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
when I click on item which really should exist. I didn't show code which generate ListView, but I can tell you that my listOfS contains 3 items:
first is Null listOfZ, second listOfZ got 2 elements, third listOfZ got 1 element.
listOfSomething.Clear();
listOfSomething.Add("first");
collection.Add(listOfSomething);
You are clearing the list here and adding one element ("first"), the 1st reference of listOfSomething is updated as well sonce both reference the same object, so when you access the second element myList.get(1) (which does not exist anymore) you get the null.
Notice both collection.Add(listOfSomething); save two references to the same arraylist object.
You need to create two different instances for two elements:
ArrayList<ArrayList<String>> collection = new ArrayList<ArrayList<String>>();
ArrayList<String> listOfSomething1 = new ArrayList<String>();
listOfSomething1.Add("first");
listOfSomething1.Add("second");
ArrayList<String> listOfSomething2 = new ArrayList<String>();
listOfSomething2.Add("first");
collection.Add(listOfSomething1);
collection.Add(listOfSomething2);
Because the second element is null after you clear the list.
Use:
String s = myList.get(0);
And remember, index 0 is the first element.
The right way to iterate on a list inside list is:
//iterate on the general list
for(int i = 0 ; i < collection.size() ; i++) {
ArrayList<String> currentList = collection.get(i);
//now iterate on the current list
for (int j = 0; j < currentList.size(); j++) {
String s = currentList.get(1);
}
}
A cleaner way of iterating the lists is:
// initialise the collection
collection = new ArrayList<ArrayList<String>>();
// iterate
for (ArrayList<String> innerList : collection) {
for (String string : innerList) {
// do stuff with string
}
}
I have String array like this
We have to pass data through response.body.getdata and this data pass in constructor like this,
List taginnerData;
"data": [
"banana",
"apple",
"grapes",
"Pears",
"Mango",
"Cherry",
"Guava",
"TorontoVsMilwaukee_12Jan19"
]
String[] myArray = new String[taginnerData.size()];
for (int i = 0; i < taginnerData.size(); i++) {
myArray[i] = String.valueOf(taginnerData.get(i));
holder.tv_channel_name.setText("" +taginnerData.get(i));
//we get any value from here to set in adapter
}

Categories