Java nested Iterator throws IllegalStateException - java

I have four different ArrayLists. I want to try out every possible combination of values.
If the first combination doesn't result in something that fulfills my constraints, I want to remove the first value from the first list and do the whole thing again with the next value.
I made an Iterator for each ArrayList but when I remove a value from the first ArrayList, it throws an IllegalStateException.
This is my code:
public static boolean revise(Haus haus1, Haus haus2) {
boolean removed = false;
Iterator<String> iteratorFarbe1 = haus1.getFarbListe().iterator();
while (iteratorFarbe1.hasNext()) {
String farbe1 = iteratorFarbe1.next();
Iterator<String> iteratorFarbe2 = haus2.getFarbListe().iterator();
while (iteratorFarbe2.hasNext()) {
String farbe2 = iteratorFarbe2.next();
Iterator<String> iteratorLand1 = haus1.getLandListe().iterator();
while (iteratorLand1.hasNext()) {
String land1 = iteratorLand1.next();
Iterator<String> iteratorLand2 = haus2.getLandListe().iterator();
while (iteratorLand2.hasNext()) {
String land2 = iteratorLand2.next();
Haus checkHaus1 = new Haus(haus1.getNummer(), farbe1, land1);
Haus checkHaus2 = new Haus(haus2.getNummer(), farbe2, land2);
if (!checkConstraints(checkHaus1, checkHaus2)) {
iteratorFarbe1.remove();
removed = true;
}
}
}
}
}
return removed;
}

This could happen because teratorFarbe1.remove() called more than once between two calls of iteratorFarbe1.hasNext()

Related

Using Collections and HashMap

I have the following class, its fairly simple, all i am doing is storing the variables from a URL.
class RM {
private String identifier, visible;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getVisible() {
return visible;
}
public void setVisible(String visible) {
this.visible = visible;
}
public RM (String identifier, //1
String visible; {
this.identifier = identifier; //1
this.visible = visible;
}
#Override
public String toString() {
return identifier + "\t" + visible + "\t";
}
}
This is stored in a collection List when i pass through the variables.
Collection<RM> attributes1 = new ArrayList<>();
I then obtain the variables stored in the identifier field and store them in an array like below:
Object rowDataprelim1 [] = new Object[1];
RM rm = null;
Iterator<RM> iterator = attributes1.iterator();
while(iterator.hasNext()) {
rm = iterator.next();
rowDataprelim1[0] = rm.identifier;
System.out.println(rm.identifier);
I then create a HashMap, the reason for doing so is because i want unique entries only.
Map<Object, Integer> numberMapping = new HashMap<>();//create a new hashmap
And also create an array of which i store identifier into rowData[0].
Object rowData[] = new Object[2];
Iterator it = numberMapping.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
rowData[0] = attributes1.get((int) pair.getValue()).identifier;
it.remove();
}
What i cant get right is the syntax to get the value of identifier from my collections list, i believe the syntax i have used is for an Arraylist.
rowData[0] = attributes1.get((int)pair.getValue()).identifier;
Can someone advise the correct syntax, i only want to get identifier and not the visible. I in fact have around 30 items in my class and only want to get 12 of them for the first section of my project. I have never used collection before and i have been told to use Collection and not ArrayList.
Any help is much appreciated.

Need help in list Java

Not sure how I can achieve this.
I have a object list, where it consists of multiple data example
ABC1231211
ABC1231111
ABC4562222
ABC4562456
Now I trying to seperate the list according to their code, which is 123 and 456, and add header and tailer to them. So my expected result would be
Head
ABC1231211
ABC1231111
Tail
Head2
ABC4562222
ABC4562456
Tail2
But the result I get is
Head
ABC1231211
Tail
Head
ABC1231111
Tail
Head2
ABC4562222
Tail2
Head2
ABC4562456
Tail2
Code
#Override
public List process(List<Detail> l) throws Exception {
for (Detail d : l) {
if (d.Code().equals("123")) {
list = generateS(d);
}
if (d.Code().equals("456")) {
list = generateR(d);
}
}
return list;
}
public List<String> generateS(Detail d) throws Exception {
try {
list.add(new HDR("Head").getHeader());
DetailL x = new DetailL();
x.setType(d.getType());
....
list.add(x.getDetail());
list.add(new TLR("Tail").getTailer());
} catch (Exception ex) {
throw new BatchException(DetailProcessor.class, ex);
}
return list;
}
Any help would be much appreciated
If you're using Java 8, you can use streams:
public void process(List<Detail> details) throws Exception {
Map<String, List<Detail>> byCode =
details.stream().collect(Collectors.groupingBy(Detail::getCode));
byCode.entrySet().stream().forEach(entry -> {
System.out.println(headerFromType(entry.getKey()));
entry.getValue().foreach(System.out::println);
System.out.println(tailFromType(entry.getKey()));
}
with headerFromType and tailFromType returning "Head"/"Head2" or "Tail"/"Tail2", depending on the given type.
You are generating a new head and tail for each element instead of adding to the already-generated list.
For each Detail, you should first check if the list exists, and if it doesn't, then call generateS or generateR as appropriate. If the list exists, you want to call e.g. sList.add(sList.size()-1, d.getDetail()). You'll of course want to replace the call d.getDetail() with the value that's supposed to go into the list or a method call that returns that value.
Then you probably want to use list.addAll(sList) to add the generated lists' contents to list.
Another solution is to generate the combined list on demand, and store the two lists separately. In that case, you would check if the corresponding list is null in the beginning of generateS or generateR, and initialize it if it is.
You create a new header and a new tail every time you call generateS or generateR but you should just create a new header once if you find a new code ( for example 123).
Solution: You collect your details into a list before you call generateS or generateR and put all the details from collected list into your DetailL.
Here is another implemetation that takes another approach:
private void go() {
List<String> list = new ArrayList<>();
list.add("ABC1231211");
list.add("ABC1231111");
list.add("ABC4562222");
list.add("ABC4562456");
String lastTag = null;
int startPos = 0;
for (int i = 0; i < list.size(); i++) {
String tag = list.get(i).substring(3, 6);
if (!tag.equals(lastTag) && lastTag != null) {
print(list.subList(startPos, i));
startPos = i;
}
lastTag = tag;
}
print(list.subList(startPos, list.size()));
}
private void print(List<String> list) {
System.out.println("Head");
for (String item : list) {
System.out.println(item);
}
System.out.println("Tail");
}
Simply "If you come accross an element with a different tag, print the previous sublist". (And print whatever is left at the end since that sublist's printout is not triggered by a new tag.)

What is the best approach to split an Arraylist based on their values

I would like to split an ArrayList that I am looping trough and set a field called active which can be true or false. But at the end of loop I would like to split this collection in two groups.. active = false and active = true, so doing this I won't need to search in database twice..
for example:
private List<Classes> searchClasses(ClassItems listItems) {
List<ClassItem> items = new ArrayList<ClassItem>();
for (Iterator<ClassItem> iterator = listItems.getItems().iterator(); iterator.hasNext();) {
ClassItems item = iterator.next();
ClassEntityManager classEnt = ClassEntityManager.search(item.getId);
if(classEnt.active()){
item.setActive(true);
items.add(item);
}
}
return items;
}
What is the best approach to do this??
Make two lists instead of one.
if(classEnt.active()) {
activeItems.add(item);
item.setActive(true);
} else {
inactiveItems.add(item);
}
Use two collections, one for actives and the other for not actives.
When you fetch the data from the DB, simply put the CalssItem in the correct list:
private List<ClassItem> searchClasses(ClassItems listItems) {
List<ClassItem> activeItems= new ArrayList<ClassItem>();
List<ClassItem> notActiveItems= new ArrayList<ClassItem>();
Iterator<ClassItem> i = listItems.getItems().iterator();
while(i.hasNext()) { //This is a better approach.
ClassEntityManager classEnt = ClassEntityManager.search(i.next().getId);
if(classEnt.active()){
item.setActive(true);
activeItems.add(item);
}else{
item.setActive(false);
notActiveItems.add(item);
}
}
List<ClassItem> ret = new ArrayList<ClassItem>(activeItems);
ret.addAll(notActiveItems);
return ret;
}
BUT, in this way, both activeItems and notActiveItems are unreacheable. Best thing to do is to have a loop outside your method that checks if the ClassItem is active or not. In this way both activeItems and notActiveItems can be deleted from the method:
private List<ClassItem> searchClasses(ClassItems listItems) {
List<ClassItem> items= new ArrayList<ClassItem>();
Iterator<ClassItem> i = listItems.getItems().iterator();
while(i.hasNext()) { //This is a better approach.
ClassEntityManager classEnt = ClassEntityManager.search(i.next().getId);
item.setActive(classEnt.active());
items.add(item);
}
return items;
}
And to use the list:
List<ClassItem> items = searchClasses(classItems);
for(ClassItem item: items){
if(item.isActive()){
//do something
}else{
//do something else
}
}
Better yet is to use the magnificient and beautiful Java 8 Stream API:
List<ClassItem> active = items.stream().filter(x->x.isActive).collect(Collectors.toList());
List<ClassItem> notActive = items.stream().filter(x->!x.isActive).collect(Collectors.toList());
or the one liner:
List<ClassItem> active = searchClasses(classItems).stream().filter(x->x.isActive).collect(Collectors.toList());
NOTES:
Your code has a return type of List<Classes>, while the returned value is of List<ClassItem>. Which is right?
Your iterator has a generic type of ClassItem while the next() method returns a ClassItems object. Which is right?

split an array list into multiple lists in java

I have an array list which when populated has a key and a value I want to know if there is a way of splitting it on repeating keys for example my current data is like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom, RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave, RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
I want it to come out more like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom]
[RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave]
[RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
Is there a way to split it on say role id or am I going about this the wrong way?
You can try by using HashMap
private static class MyItemHashMap extends HashMap {
public Item add(Item item) {
get(item).add(item);
return item;
}
public List get(Item key) {
List list = (List) get(createItemKey((Item) key));
return list == null ? createItemEntry((Item) key) : list;
}
private List createItemEntry(Item item) {
List list = new ArrayList();
put(createItemKey(item), list);
return list;
}
private Object createItemKey(Item item) {
return item.getSplitterProperty();
}
}
public static void main(String[] args) {
MyItemHashMap itemMapped = new MyItemHashMap();
List items = Arrays.asList(new Object[]{new Item("A"), new Item("B"),
new Item("C")});
for (Iterator iter = items.iterator(); iter.hasNext();) {
Item item = (Item) iter.next();
itemMapped.add(item);
}
}
If it is an ArrayList, there is no built-in function to split data like this; you will have to do it manually. If you know the number of consecutive fields that make a single structure, this shouldn't be too hard; something like this:
// 6 because there are 6 fields
for (int i = 0; i < arrayList.size(); i = i + 6) {
List thisList = arrayList.subList(i, i + 5);
// ... Now do whatever you want with thisList - it contains one structure.
}
If the number of fields can change then you'll have to do something a little more dynamic and loop through looking for a RoleID field, for example.
I'd use a HashMap to seperate the data instead of one long ArrayList ( you shouldn't have stored the data like this in the first instance )
HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>;
// For each list:
ArrayList<String> arr = new ArrayList<String>;
arr.add("each element");
hm.put("RoleID_123.0", arr);
This way you will end up with a three dimensional structure with a key ( "RoleID..." ) pointing to its child elements.
Try this
String[] str=new String[]{"RoleID_123.0", "UserHandel_tom", "Password_12345.0", "prevPassword_null", "userCaption_thomas", "Email_tom#tom.tom", "RoleID_124.0", "UserHandel_dave", "Password_ghadf", "prevPassword_sdfsd", "userCaption_david", "Email_dave#dave.dave", "RoleID_125.0", "UserHandel_trevor", "Password_tre", "prevPassword_null", "userCaption_trev", "Email_trev#trev.trev"};
List<String> list=new ArrayList<>(Arrays.asList(str));
List<String> subList=list.subList(0,5);
You can try something similar to this
If you feel like taking a Linq-ee Libraried approach, this is about as good as it gets, and it requires use of a couple delegate objects:
import static com.google.common.collect.Collections2.filter;
import static com.google.common.collect.Collections2.transform;
//...
final List<String> yourList = //...
final int RECORD_LENGTH = 6;
Collection<String> roleIdValues = filter(yourList, new Predicate<String>() {
public boolean apply(#Nullable String input) {
return input != null && input.startsWith("RoleID");
}
});
Collection<Collection<String>> splitRecords = transform(roleIdValues, new Function<String, Collection<String>>() {
#Nullable public Collection<String> apply(#Nullable String input) {
return yourList.subList(yourList.indexOf(input), RECORD_LENGTH);
}
});
If Oracle had delivered Java 8 on time you would be able to do this in a way more slick manor. Ironically the reason you cant was provided by the same people providing the guava library

Custom Linklist class error

class Link {
public Link next;
public String data;
}
public class LinkedList {
public static void main(String[] args) {
String myArray[] = new String[2];
myArray[0] = "John";
myArray[1] = "Cooper";
Link first = null;
Link last = null;
while (myArray.hasNext()) {
String word = myArray.next();
Link e = new Link();
e.data = word;
//... Two cases must be handled differently
if (first == null) {
first = e;
} else {
//... When we already have elements, we need to link to it.
last.next = e;
}
last = e;
}
System.out.println("*** Print words in order of entry");
for (Link e = first; e != null; e = e.next) {
System.out.println(e.data);
}
}
}
LinkedList.java:16: cannot find symbol symbol : method hasNext()
location: class java.lang.String
while (myArray.hasNext()) {
^ LinkedList.java:17: cannot find symbol
symbol : method next() location: class java.lang.String
String word = myArray.next();
^ 2 errors
Few Questions...
Why did this error occur, i am trying to pass my Array of Strings. Still its not taking.
Can't we not declare Array of Strings like in JavaScript way.
String myArray[] = ["assa","asas"];
What does the hasNext() and the next Method do?
Java arrays don't have next and hasNext methods on them. You are probably thinking of iterators, which are typically used with container classes/interfaces such as java.util.List.
Note that you can initialize String arrays thus:
String[] myArray = { "foo", "bar" };
Here is a much more succinct way to iterate through the array
for(String word : myArray) {
//Keep the rest of the code the same(removing the String word = myArray.next(); line
}
That will iterate through the array, assigning the current value to word at each pass.

Categories

Resources