I have the following loop and I got PMD static check message :avoid instantiating new object in loop
Voc is constructor .
I need to create new instance in every loop ,there is a way to that in different way?
for (AnnoValue currValue : collection.getValues())
{
Voc(termName, this.nameSpace, this.alias);
}
First ensure is there anyway you could reuse this Voc instance for each iteration. In that case, move this instance creation out of the loop and possibly clear the state information at the start of the loop.
Voc vocInst = new Voc();
vocInst.setNamespace(this.nameSpace);
vocInst.setAlias(this.alias);
for (AnnoValue currValue : collection.getValues())
{
vocInst.clear();
vocInst.setTermName(termName); // I believe this is local variable and the rest of the parameters are instance variables.
.....
.....
}
Related
I am facing a very strange situation. I add an object to an arrayList in a loop, but it is replaced by the next object. Actually second item is duplicated. ( It replaces the first item as well as inserts another object to the ArrayList.)
This is my code. I have done the debugging and included the comments where needed. Could someone point out why this happens? I am taking the object details from the database and those are working as expected.
public class Serv
{
#Autowired
GrpHeader objGrpHeader;
#Autowired
CompPesoOutgoingMsg objMsg;
#Autowired
OutwardMessage objOutwardMessage;
public List<OutwardMessage> outgoingMessagesAsSingleTrx()
{
List<OutgoingMsg_Obj> trxList = myRepo.getTrx("5");
List<OutwardMessage> myTrxList = new ArrayList<>();
for (OutgoingMsg_Obj outgoingMsg : trxList)
{
BigDecimal trxAmt = outgoingMsg.getIntrBkSttlmAmt().getTrxn_amt();
trxAmt = (trxAmt).divide(new BigDecimal(100));
GrpHeader grpHeader = objGrpHeader;
CompPesoOutgoingMsg outMsg2 = objMsg;
OutwardMessage objOutwardMessage2 = objOutwardMessage;
outgoingMsg.setRmtInf(objRmtInf);
outgoingMsg.setPmtTpInf(objPmtTpInf);
outMsg2.setHeader(grpHeader);
outMsg2.setCdtTrfTxInf(Arrays.asList(outgoingMsg));
objOutwardMessage2.setObjMsg(outMsg2);
**//Here, Correct object details are printed**
log.info("outwardMsg 100 {} ", objOutwardMessage2);
//Add Item to the list
myTrxList.add(objOutwardMessage2);
for (OutwardMessage outwardMsgx : myTrxList)
{
//1. When this loop executed first time, first object details are printed
//2. When printed second time, first added object is no more. And second added object is there twice.
log.info("outwardMsg 101 {} ", outwardMsgx);
}
}
return myTrxList;
}
}
You have a single reference. By setting the objOutwardMessage2to objOutwardMessageyou are just changing the data inside the reference.
Since no new object is created for each iteration, the same objOutwardMessage2 value is getting replaced each time.
Try
OutwardMessage objOutwardMessage2 = new OutwardMessage();
and copy the value of objOutwardMessage to the newly created objOutwardMessage2.
I was wondering if it is possible to reset the value of a variable from another class. For example I have this variable in a HillClimber (hc) class:
public int ballWeight = 200;
What I want to do is run a simulation of a game with the ball weighting at this value. When it is finished I want to set the value to 201 from another class and begin the simulation again, and after that increase to 202 and start another and so on. My problem is that every time I restart the simulation the ballWeight variable is reset to 200. I have tried using a setter method in the HillClimber class:
public int setBallWeight(int ballWeight) {
return this.ballWeight = ballWeight;
}
and called it from another class at the end of a simulation:
hc.setBallWeight(hc.ballWeight+1);
but this does not seem to work as the variables stored value is not changed. Does anyone know how I can do this so the stored value of ballWeight will be increased by 1 each time a simulation ends? Or is this even possible? Thanks.
Usually in a POJO you have what are called a getter and a setter method for every variable of the object. In your case:
public class HillClimber{
private int ballWeight;
public HillClimber(){
this.ballWeight = 200;
}
public void setBallWeight(int ballWeight){
this.ballWeight = ballWeight;
}
public int getBallWeight(){
return this.ballWeight;
}
}
In this way you can access the variable ballWeight via get and set method. You don't access it directly like in hc.ballWeight, which is possible but is a bad practice, and prevent this access type declaring your variable as private (meaning that only the class in which it is declared can directly access it).
To fullfill your request of adding one at every run of the game you can therefore call
hc.setBallWeight(++hc.getBallWeight()); //Equivalent to hc.setBallWeight(hc.getBallWeight() + 1);
I usually don't use this approach if the class isn't automatically generated (as in an Hibernate context), but instead declare another method in the HillClimber class
public void incrementBallWeight(int ballWeightToAdd){
this.ballWeight += ballweiGhtToAdd; //Equivalent to this.ballWeight = this.ballWeight + ballweiGhtToAdd;
}
or if I always need to add only one to my variable
public void incrementBallWeight(){
this.ballWeight++;
}
and then simply call incrementBallWeight after every game run.
NB: to have this working you will have to use always the same instance of HillClimber. In your main
public class Game{
private HillClimber hc = new HillClimber(); //Create the instance and sets ballWeight to 200
public static void main(String[] args){
playGame();
hc.incrementBallWeight(); //ballWeight == 201
playAnotherGame()
hc.incrementBallWeight(); //ballWeight == 202 -> Always the same instance of HillClimber (hc)
.
.
.
}
}
EDIT
I think your problem is greater than that. You are asking to save the state of a variable ( meaning that this value should be available also if you turn off and on your pc) without using a permanent storage. This is simply unachievable.
You should rethink your program (and I mean java program, not a "game run") to not stop after every game run. You can do this in different ways: via Swing GUI, via user input from stdin and so on. If you want some help on this topic, we need to know more of your code (maybe putting the whole of it is best).
OR you can use a file to store your value, which is not as difficult as you think. (Also).
Hi i am trying to add the values to list as show in below code. i am getting error.
if i use like below
for (String n2 : number ) {
List<String> ARRAY = new ArrayList<String>();
if (!ARRAY.contains(n2)) {
Email(n2);
ARRAY.add(n2);
}
}
if i am using above. Though already email sent with value n2 again it is sending again. For first it has to sent but for second time n2 should be in array but still it sending. any one help. if n2 is passed to email second time it should not pass.
I am re-posting question as pervious one seems not clear i guess.
You need to move the ARRAY outside of the for loop
List<String> ARRAY = new ArrayList<String>(); // maybe as a class field
for (String n2 : number ) {
if (!ARRAY.contains(n2)) {
Email(n2);
ARRAY.add(n2);
}
}
List<String> ARRAY = new ArrayList<String>();
This line needs to be outside of your loop.
Why?
Simple. It's an issue of scope. Scope is the the lifetime and accessibility of a variable. In this case, you declare it inside of a loop, so the scope of that variable is, you guessed it, the loop. When the loop exits, the variable is destroyed.
You need to move it outside, so that the variable persists for the lifetime of the loop.
Extra Reading
Please, read the Java Naming Conventions.
Here is the method
public void addModuleToStudent(Module aModule)
{
int position = 0;
if(position > 3)
{
System.out.println("Error: Student already has four modules\n");
}
else
{
moduleArray[position] = aModule;
position++;
}
}
The problem is that the position doesn't seem to be increment the position variable because when ever I add a module class it occupies the 1st position in the the array and when I add another instead of being added into the second position it overwrites the first.
Yes, position is a local variable. Every time you call addModuleToStudent, you get a new variable, initialized as 0.
It sounds like you want to make this an instance variable instead, so that it persists between method calls.
Better yet, don't use an array instead - use an ArrayList<Module> instead, and then you can just use:
public void addModuleToStudent(Module module)
{
if (modules.size() > 3)
{
throw new SomeAppropriateException("Cannot have more than 4 modules");
}
modules.add(module);
}
position is a local variable, each time you call your addModuleToStudent method it is re-initialized to zero. So, do something like
int position=0
public void addModuleToStudent(Module aModule)
{
//your logic here
}
You're resetting position to zero every time the method is called
Either make position an instance variable in the class, or use a Vector<Module> or an ArrayList<Module> instead of an array and call:
modules.add(aModules);
to add each new module onto the end of the list.
I am assuming that you are calling the addModuleToStudent method each time and that you want to add a module and that moduleArray is some global variable...
The problem here is that whenever you call the method, position is always initialized to 0. To solve your problem, what you might want to do is to remove the int position = 0; line and use the position variable as a global variable.
My managed bean :
public List<String> getLiQuickNav(){
System.out.println("I'm here...");
List<String> l = new ArrayList<String>();
l.add("toto");
l.add("tata");
l.add("titi");
return l;
}
My forEach :
<c:forEach var="categorie" items="#{mainControleur.liQuickNav}">
<h:outputLabel value="${categorie}"/>
</c:forEach>
My output stream :
I'm here...
I'm here...
I'm here...
I'm here...
As you can see "getLiQuickNav( )" is call 4times by my ForEach. But I just wan't to call "getLiQuickNav( )" one time...
How to call it just one time ?
Bonus question:
Why "getLiQuickNav( )" is call 4time whereas I have only 3item "tata,titi,toto" ?
Thank's
You can't control the number of times that getLiQuickNav() is called - consider caching your list so it isn't rebuilt between calls.
private List<String> l;
public List<String> getLiQuickNav()
{
if ( l == null )
{
System.out.println("I'm here...");
l = new ArrayList<String>();
l.add("toto");
l.add("tata");
l.add("titi");
}
return l;
}
As well you should be using <ui:repeat/> rather than <c:forEach/>. See this blog entry for why.
Answer
You're reinitializing the state in a getter every time. That is meant to be an accessor, not a way to initialize state. Don't create the list in getLiQuickNav, create in a constructor or setter.
Bonus
The first time you call getLiQuickNav() you initialize the list, the reference to this list gets returned and stored in a scope to evaluate your expression (.liQuickNav) and then the getLiQuickNav() is called by convention 3 more times for each item in the list.
It should get called once if you return the same list every time. You're returning a new one every time.
Getter's in Java (in any context, to include for Faces Managed Beans) should not generate anything - they should just return a value. Create the list before hand and return it.