enhanced for loop stops recognizing variable - java

I'm trying to make a bukkit plugin, but this is a java problem. I have an enhanced for loop that, for some reason, only recognizes the declared loop variable in one specific instance. Here is an excerpt of the code:
for(String categoryName : catString)
{
if(this.getConfig().getConfigurationSection("Shops." + ShopName + ".Categories." + categoryName).getKeys(false).contains("SubCategories"))//If it has subcategories
{
Set<String> subCategories = this.getConfig().getConfigurationSection("Shops." + ShopName + ".Categories." + categoryName + ".SubCategories").getKeys(false);
String[] subCatString = new String[subCategories.size()];
int subCatAmount = subCategories.size();
holder = subCatAmount;
pageAmount = 0;
while(holder > 0)
{
pageAmount++;
holder -= 45;
}
Inventory[] subCategoryInvs = new Inventory[pageAmount];
cellIndex = 0;
pageIndex = 0;
holder = categoryAmount;
placeHolder = null; //Placeholder Inventory, will be loaded into the HashMap later, set to null so that it is fresh for subcategories.
while(pageIndex < pageAmount)
{
The line with the if statement recognizes the variable "categoryName", but in the very next line of code, where the Set is defined, I get a red underline telling me that "categoryName" is not a variable. In addition, if I add a statement before the if statement that uses "categoryName" in any way whatsoever, I am told that it isn't a variable. What gives?
BTW, I am using Eclipse, if that is relevant. Also, no, this isn't the complete for loop.
EDIT: I was able to work around it by using the non-enhanced for loop, meaning that instead of using categoryName, I had to use catString[index], which is fine, I guess. I'm still wondering what was wrong with my original for loop, as I used the same variable name throughout.

Related

Count elements of a list using While loop in java

I am passing some parameters in the URL and then I add them in a list. My list has a limit of 5 elements. So if someone adds 6th element in the URL the list would simply ignore it. So I am trying to use a counter but the logic is not working as desired. I am using While loop to achieve this. So if list size is smaller than 5 set the agencyCds otherwise just return the list.
private List<IUiIntegrationDto> generateViewIntegrationReportData(ESignatureIntegrationConfig eSignConfig) throws Exception {
int counter = 1;
if(eSignConfig.getAdditionalAgencyCds() != null ) {
List<String> combinedAgencyCds = new ArrayList<String>();
for(String agencyCd : eSignConfig.getAgencyCd()) {
combinedAgencyCds.add(agencyCd);
}
StringTokenizer token = new StringTokenizer(eSignConfig.getAdditionalAgencyCds().toString(), StringConstants.COMMA);
while(token.hasMoreTokens()) {
combinedAgencyCds.add(token.nextToken());
}
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
// eSignConfig.setAgencyCd(combinedAgencyCds);
}
List<IUiIntegrationDto> intgList = getUiIntegrationManager().retrieveUiIntegrationReportData(eSignConfig.getAgencyCd(), eSignConfig.getCreatedDays(),
eSignConfig.getLob(), eSignConfig.getTransactionStatus(), eSignConfig.getAccounts(), eSignConfig.getSortKey(), eSignConfig.getSortOrder());
return intgList;
}
I am not completely sure about this logic if it is correct or if there is nay better approach.
Thanks
Try this instead of the last while in your code:
if(combinedAgencyCds.size() <= 5) {
eSignConfig.setAgencyCd(combinedAgencyCds);
} else {
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, 5));
}
The full combined list will then be used if it is less than 5 in size. Otherwise, only the first 5 elements are used.
Edit: Or even better:
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, Math.min(5, combinedAgencyCds.size())));
Ok so let's break down what your code is currently doing.
int counter = 1;
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
This snippet of code has a couple things wrong best I can tell. First, this loop has the possibility of running forever or not at all. Because combinedAgencyCds is never being manipulated, the size won't ever change and the logic being checked in the while loop never does anything. Second, there's a more efficient loop for doing this, assuming you don't need the counter variable outside of its usage in the while loop and that is using for loops.
Example syntax is as follows:
for (int i = 0; i < combinedAgencyCds.size(); i++) {
if (i < 5) {
// Do your logic here.
}
else {
break; // Or handle extra values however you want.
}
}
Notice there is no need for the explicit declaration for a counter variable as "i" counts for you.
Now in your actual logic in the loop, I'm not sure what the setAgencyCd method does, but if it simply sets a list variable in the eSignConfig like it appears to, repeating it over and over isn't going to do anything. From what I can see in your code, you are setting a variable with the same value 5 times. If you need any more explanation just let me know and I will be happy to revise the answer.

reference array using variable in Java

I please bear with me, I have been using Java for 2 days and i've hit a bit of a hurdle.
I am using Talend to perform a count using the tMemorize and tJava components but this may be a question for a Java developer. I have previously posted an issue with using this method within a joblet by my new issue is more Java related which can be viewed here:
using Joblets in talend with tMemorize and tJavaFlex
I need to reference an array generated by the java code talend. I cannot reference this element directly because of an issue with using tJavaFlex within multiple joblets: Java renames joblets each time they are used.
It may be useful to understand how my code works in normal circumstances (excluding the use of joblets).
int counter = 1;
if (EnquiryID_mem_1_tMemorizeRows_1[0].equals(EnquiryID_mem_1_tMemorizeRows_1[1]))
{
counter++;
}
row3.counter = counter;
The EnquiryID_mem_1_tMemorizeRows_1[0] and EnquiryID_mem_1_tMemorizeRows_1[1] is what I need to reference.
To overcome this I have written the following code.
String string = currentComponent;
String[] parts = string.split("_");
String part1 = parts[0];
String part2 = parts[1];
String joblet = part1+'_'+part2;
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
if (newrow[0].equals(newrow[1]))
{
counter++;
}
row3.counter = counter;
However I get the following error:
The type of the expression must be an array type but it resolved to String
I understand that the newrow variable is a string and I am using it to reference an array. I have searched far and wide online for a resolve but I cannot fine one. Can someone help me please?
Thank you
Here is the talend code that my code should reference. I have taken it from the currentComponent that I am using to when it changes to one not in use directly.
currentComponent = "mem_1_tMemorizeRows_1";
// row1
// row1
if (execStat) {
runStat.updateStatOnConnection("row1" + iterateId,
1, 1);
}
for (int i_mem_1_tMemorizeRows_1 = iRows_mem_1_tMemorizeRows_1 - 1; i_mem_1_tMemorizeRows_1 > 0; i_mem_1_tMemorizeRows_1--) {
EnquiryID_mem_1_tMemorizeRows_1[i_mem_1_tMemorizeRows_1] = EnquiryID_mem_1_tMemorizeRows_1[i_mem_1_tMemorizeRows_1 - 1];
}
EnquiryID_mem_1_tMemorizeRows_1[0] = row1.EnquiryID;
mem_1_row2 = row1;
tos_count_mem_1_tMemorizeRows_1++;
/**
* [mem_1_tMemorizeRows_1 main ] stop
*/
/**
* [mem_1_tJavaFlex_1 main ] start
*/
currentComponent = "mem_1_tJavaFlex_1";
// mem_1_row2
// mem_1_row2
if (execStat) {
runStat.updateStatOnConnection("mem_1_row2"
+ iterateId, 1, 1);
}
mem_1_row3.QuoteID = mem_1_row2.QuoteID;
mem_1_row3.EnquiryID = mem_1_row2.EnquiryID;
if (EnquiryID_mem_1_tMemorizeRows_1[0]
.equals(EnquiryID_mem_1_tMemorizeRows_1[1])) {
rower++;
}
mem_1_row3.rower = rower;
tos_count_mem_1_tJavaFlex_1++;
/**
* [mem_1_tJavaFlex_1 main ] stop
*/
/**
* [mem_1_tMap_1 main ] start
*/
currentComponent = "mem_1_tMap_1";
Thank you to everyone who has helped so far.
This
if (newrow[0].equals(newrow[1]))
Tries to pick the first and second element of the array newrow. Unfortunately you declare newrow as
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
which is not an array but a String. That syntax in the if will not work with a String. I am not sure what you are trying to do but that if check will not work.
EDIT:
If you are trying to pick up char from a string you need to use charAt(index).
If you want to treat newrow as an array you have to declare it as such and pass appropriate elements to it.
EDIT 2: I think you are trying to pass the actual data in joblet to newrow in this:
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
But what happens here is that everything is concatenated in one String so you need to figure out where the data you are looking for (part[0] and part[1] I assume) is present in that String so you can pull them out (basically what indices contain the values you are looking for).
An example of how newrow will look after that assignment:
"EnquiryID_part1_part2_tMemorizeRows_1"
So "part1" will start at index 10 and will end at index 14. I am just using "part1" here, but it would have whatever value is stored in part1 variable.
If you can show us what you expect it to look like that would help.
I'm not super familiar with talend (understand: not at all). But it sounds like you have some sort of attribute of a generated class (say myGeneratedObject) and you want to access it by name.
In that case, you could do something like:
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
Field field = myGeneratedObject.getClass().getField(newrow);
if (field.getClass().isArray()) {
if(Array.get(field, 0).equals(Array.get(field, 1)) {
counter++;
}
}
It all depends how you access that field really and where it's declared. But if it's an attribute of an object, then the code above should work, +/- contextual adjustments due to my lack of knowledge of the exact problem.

I do not understand this HeadFirst Java exercise [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 months ago.
Improve this question
I'm reading Head First Java and an exercise is confusing me a little bit. The Original instructions of the exercise are irrelevant, however, the point is to be able to solve it with out just compiling the code and running it, which would just spit out the answer. I am quite confused and am trying to play the debugger and go step by step each line of code and see what is happening. I have added my comments to the code to make sure I am understanding it. Just need help understanding for example what the count is at a specific point and such. Here is the original code, with one line added myself, which i've noted. Some of the lines I will note which I don't understand the best.
**Update: So I gave the best understanding on my code. Questions I have about certain lines are in the comments. If anyone can maybe do a step by step approach of what happens would make it a lot more understandable. Thank you all for your help in advance. I am new to StackOverFlow so hopefully this was the correct way of asking a question.
public class Mix4
{
int counter = 0; //This is setting the variable counter to 0.
public static void main (String[] args)
{
int count = 0; //This is setting the variable count to 0.
Mix4[] m4a = new Mix4[20];//This is initializing an array of 20 m4a objects to null.
int x = 0; //This is setting the variable x to 0;
while ( x < 9 )
{
m4a[x] = new Mix4(); //This actually creates the m4a object at array index 0.
m4a[x].counter = m4a[x].counter + 1;
//This line is very confusing. How can you use a dot operator on a variable?
//I am saying variable because as stated above there is a int counter = 0;
count = count + 1; //This increments the variable count. Why do this though?
count = count + m4a[x].maybeNew(x);
//The count variable again is being implemented but this time it calls the
// maybeNew method and it is passing a 0 as as the argument? Why do this?
x = x + 1; // x is being incremented.
System.out.println(count + " " + m4a[1].counter);
//What is this printing and when does this print?
}
public int maybeNew(int index)
{
if (index < 5)
{
Mix4 m4 = new Mix4(); //Creating a new object called m4.
m4.counter = m4.counter + 1;
//Same question about this from the code of line stated above using dot
//operators on variables.
return 1; //Where does 1 be returned to? I thought you can only have one
//return statement per method?
}
return 0; // I thought only 1 return statement? I have no idea what these return
// statements are doing
}
}
}
m4a[0].counter = m4a[x].counter + 1;
//This line is very confusing. How can you use a dot operator on a variable?
//I am saying variable because as stated above there is a int counter = 0;
m4a is an array of Mix4 objects. You can call object methods or properties(variables) using the . operator
count = count + m4a[x].maybeNew(x);
//The count variable again is being implemented but this time it calls the
// maybeNew method and it is passing a 0 as as the argument? Why do this?
maybeNew() return an int. You are trying to increase the count by whatever number maybeNew(x) returns. x is the value of m4a[0], if x = 0.
System.out.println(count + " " + m4a[1].counter);
//What is this printing and when does this print?
This prints at end of your program. It prints the counter value for the Mix4 object at index 1 in the m4a array
return 1; //Where does 1 be returned to? I thought you can only have one
//return statement per method?
}
return 0; // I thought only 1 return statement? I have no idea what these return
// statements are doing
First of all, a method may or may not return a value. In you method, you want it to return an int. So when you call it here count = count + m4a[x].maybeNew(x);, it like saying, whatever number maybeNew(x) returns, add that to count.
Your first return 1 is inside of a conditional statement. If the condition is satisfied, return 1, else return 0
int x = 0; //This is setting the variable x to 0;
You got this part right
Now inside while loop in the 1st iteration x = 0;
Mix4[] m4a = new Mix4[20];
This again as you correctly guesses is just defining of an array. Simply putting it is a group of 20 reference of type Mix which woould point to the actuall Object of type Mix. Now you have to assign these objects to the references which is what we are doing in the while loop.
m4a[x] = new Mix4();
Here in 1st iretartion we are doing m4a[0] = new Mix4(); so the element at index 0 is initialized.
m4a[0].counter = m4a[x].counter
Here we are simply accessing the counter of the actual object and assigning value to it.
How can you use a dot operator on a variable?
First if all m4a[0] has been initialized. Next thing you need to know is acess modifieer. If you look at the statement
int counter = 0;
No access modifer is specified which means it has default access modifier. Now for default access modifier visibilty of a variable is in the same class and same package(No need of getter/setter methods).
Also note that counter is an instance variable(not local variable) and instance variables are assigned default values(for int it is 0, for String it is null and so on...)
Try to debug the code step by step with this basic understanding.
Where does 1 be returned to? I thought you can only have one
return statement per method?
You may have have one return statement for one branch in your function, its not restricting to have one one return statement per function, its should be only one return statement for one logic path. Like :
public int DoStuff(Foo foo) {
if (foo == null) return 0;
...
return 1; // any thing
}
m4a[0].counter = m4a[x].counter + 1;
//This line is very confusing. How can you use a dot operator on a variable?
//I am saying variable because as stated above there is a int counter = 0;
m4a is an array ofMix4Class objects. You can call object methods or properties using the . operator.
From Using Objects
Code that is outside the object's class must use an object reference or expression, followed by the dot (.) operator, followed by a simple field name, as in:
objectReference.fieldName
System.out.println(count + " " + m4a1.counter);  
//What is this printing and when does this print?
From System.out.println()
Prints an Object and then terminate the line. This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().
It will print the count value, and counter value for the Mix4 object at index 1 in the m4a array.
Your code as you have shown above will not compile for two reasons:
You have the System.out.printlninside the while loop; this will result in a NullPointerException as when the compiler gets to m4a[1].counter the m4a[1] object has not been created. Only m4a[0] has been created. Alternatively you can leave this line where it is but change it to m4a[0].counter
You have the maybeNew(int index) method declaration inside main; this is mostly likely just a mistake with your curly brackets but just so you know you can't declare a method inside another method; main is a method and so you must declare maybeNewoutside it but call it from within main
public class Mix4 {
int counter = 0;
public static void main (String[] args) {
int count = 0;
Mix4[] m4a = new Mix4[20];
int x = 0;
while (x < 9) {
m4a[x] = new Mix4();
m4a[x].counter = m4a[x].counter + 1;
count = count + 1;
count = count + m4a[x].maybeNew(x);
x = x + 1;
// System.out.println(count + " " + m4a[0].counter);
}
System.out.println(count + " " + m4a[1].counter);
}
public int maybeNew(int index)
{
if (index < 5)
{
Mix4 m4 = new Mix4();
m4.counter = m4.counter + 1;
return 1;
}
return 0;
}
}

Docx4j: Insert item X times after current item under parent

I'm attempting to use DOCX4J to parse and insert content into a template. As part of this template I have loops which I need to copy everything inbetween two markers, and repeat all that content X times.
The relavant code is as follows:
public List<Object> getBetweenLoop(String name){
String startTag = this.tag_start + name + "_LOOP" + this.tag_end;
String endTag = this.tag_start + name + this.tag_end;
P begin_loop = this.getTagParagraph(startTag);
P end_loop = this.getTagParagraph(endTag);
ContentAccessor parent = (ContentAccessor) this.getCommonParent(begin_loop, end_loop);
List<Object> loop = new ArrayList<Object>();
boolean save = false;
//Cycle through the content for the parent and copy all the objects that
//are between and including the start and end-tags
for(Object item : parent.getContent()){
if(item.equals(begin_loop) || item.equals(end_loop))
save = (save) ? false : true;
if(save || item.equals(end_loop)){
loop.add(XmlUtils.deepCopy(item));
}
if(item.equals(end_loop)){
//Here I want to insert everything copied X times after the current item and then exit the for loop.
//This is the part I'm not sure how to do since I don't see any methods "Insert Child", etc.
}
}
return loop;
}
getTagParagraph successfully returns the object representing the paragraph for the tag sent. This works beautifully.
getCommonParent returns the shared parent between the two supplied tags. This works beautifully.
My problem is, as commented, how to insert the newly copied items into the appropriate place.
If you're looking to insert all the objects you have stored in your loop collection, you simply need to do something like this (in the conditional you've commented):
item.getContent().addAll(loop);
item represents the end_loop object (a paragraph or whatever), and inserts all the objects you've collected into the loop collection. (addAll may require an int argument too, I can't recall, but if it does that's just the desired index within the overall MainDocumentPart.getContent() JAXB document representation).
#Ben, thank-you!
If you know of any instances where below wouldn't work, please let me know.
I had actually just figured out something very similar, but ended up changing a lot more code. Below is what I put together.
public void repeatLoop(String startTag, String endTag, Integer iterations){
P begin_loop = this.getTagParagraph(startTag);
P end_loop = this.getTagParagraph(endTag);
ContentAccessor parent = (ContentAccessor) this.getCommonParent(begin_loop, end_loop);
List<Object> content = parent.getContent();
Integer begin_pointer = content.indexOf(begin_loop);
Integer end_pointer = content.indexOf(end_loop);
List<Object> loop = new ArrayList<Object>();
for(int x=begin_pointer; x <= end_pointer; x = x + 1){
loop.add(XmlUtils.deepCopy(content.get(x)));
}
Integer insert = end_pointer + 1;
for(int z = 1; z < iterations; z = z + 1){
content.addAll(insert, loop);
insert = insert + loop.size();
}
}

Problem with my for loop. I have never used this type before and it's not working like a regular loop

I have a Project class that holds a name and various other attributes. Everytime a new Project is made it is added to an ArrayList.
ArrayList<Project> mProject = new ArrayList<Project>();
I have most of the code in a different question. I don't feel like I should ask it there as it has a different question on it. But if you want to check out more of the code it's here:
Can I use a method from a different class that I have added to an ArrayList?
And here is where I'm stuck. This is the first time I've used this type of loop before and I don't know what's going on. I have seen tutorials just pass over this loop with a "you should know what happens here" attituded. So if you could explain this loop that would be great also.
And on to the code:
System.out.println("Select one of the fallowing projects:");
for (Project proj : mProject){
int i= 1;
i++;
System.out.println( i + ": " + proj.returnName());
}
My output is this:
Select one of the fallowing projects:
2: Greg
2: Mike
It looks like it's not going though the code. So I'd love an explanation or a tutorial with this loop. Thanks.
If I use a regular loop how whould I go about using the methods from the mProject arraylist?
for ( int i = 0; i<= mProject.size() ; i++){
Project proj = mProject;// This won't compile.
if (choice == proj.returnName()){
}
}
If you move the int declaration out of the loop it will increment as you would expect, it is getting reassigned every time:
int i= 1;
for (Project proj : mProject){
i++;
System.out.println( i + ": " + proj.returnName());}
your int Variable gets initalised with 1 in the for each loop, then incremented. In the next iteration, it gets initialised with 1 again, then incremented.
int i= 1;
System.out.println("Select one of the fallowing projects:");
for (Project proj : mProject){
i++;
System.out.println( i + ": " + proj.returnName());
}
This should work properly
Its basically just a different way of writing a for loop, also known as a foreach loop.
http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html
In your code example, the variable proj gets set to the next item in the list mProject. This happens until the list has nothing left to iterate through.
The variable i is local to the for loop, so it is being recreated each time, as others have said. In other words, every iteration of this loop will make i = 2, as you can see from your output.
See that you delcare the "int i = 1; " inside the loop.
So, every time the loop "loops", i gets the value 1 again.
It should be:
int i =1;
for(Project proj: mProject) {
i++;
System.out.println( i + ": " + proj.returnName());
}
See the "int i = 1 ; " out of the loop ?
This type of loop is known as a foreach loop in Java. Basically, it's shorthand for saying, "for each item in this array/collection/iterable, do ..."
The shorthand is nice, but the downside, as you have run into, is that you don't have access to the index or iterator inside the loop when you use this form. So you should either separately track the index (like you're already trying to do, see Terrell's answer for the correct way), or use standard loop syntax, e.g. for(int i=0; i<mProject.length; i++)
for (Project proj : mProject){
System.out.println( proj.returnName() );
}
means
For each Project in the Project Set mProject, which has been defined as:
{ GregProject, MikeProject }
Print out that project's returnName. proj is re-evaluated at each step of the loop, to point to the next Project in the Set.

Categories