I am having a list of queues as follows:
public class QueueSelection {
public List initQueueCollection()
{
QueueLoad d1 = new QueueLoad("QUEUEA1", "QUEUEB1", true);
QueueLoad d2 = new QueueLoad("QUEUEA2", "QUEUEB2", false);
QueueLoad d3 = new QueueLoad("QUEUEA3", "QUEUEB3", true);
QueueLoad d4 = new QueueLoad("QUEUEA4", "QUEUEB4", false);
List list = new ArrayList();
list.add(d1);
list.add(d2);
list.add(d3);
list.add(d4);
return list;
}
Now from the main method, i call the above method like,
QueueSelection selection = new QueueSelection();
List<QueueLoad> queueList =selection.initQueueCollection();
When the first input/file comes, queue is checked to see which one of these is false, so I am fetching the second one ("QUEUEA2", "QUEUEB2", false);
As soon as I fetch it, I should change the status to true like ("QUEUEA2", "QUEUEB2", true); I am doing it using
for (QueueLoad s:queueList)
{
if(s.getStatus()==false)
{
str1=s.getQueueName1();
str2=s.getQueueName2();
str3=s.getStatus();
particularCollection=s;
System.out.println(s);
particularCollection.setStatus(true);
particularCollection.setQueueName1(str1);
particularCollection.setQueueName2(str2);
int j=queueList.indexOf(particularCollection);
System.out.println("The index is"+j);
s = new QueueLoad(str1, str2, true);
newqueueList=queueList.set(j, s);
And the list is updated. Now when the second input comes, since in the first line it is seeing the List<QueueLoad> queueList =selection.initQueueCollection();
it is always getting the old list and not the updated one.
Please help.
Now when the second input comes, since in the first line it is seeing
the List queueList =selection.initQueueCollection(); it is
always getting the old list and not the updated one.
I interpret this to mean that you don't want the init method to be invoked again 'when the second input comes'.
There are a lot of ways to address this. Have you considered moving the init method into the constructor for QueueSelection, for example?
Take a look at the javadocs for ArrayList.set. It returns the old value at that location. So you'll want to do:
queueList.set(j, s);
newqueueList = queuelist;
If I have understood you correctly then you're problem is that at each new input you are intializing a new list. Maybe just put queueList as class attribute?
Also:
newqueueList=queueList.set(j, s);
I think set() returns the object that was previously at that index. So your newqueueList would actually contain a QueueLoad object.
Since you haven't shown your main() method, I'm not certain what it looks like, but something along these lines should work:
Instead of:
QueueSelection selection = new QueueSelection();
List<QueueLoad> queueList =selection.initQueueCollection();
Declare queueList outside the method something like this:
private static List<QueueLoad> queueList = null;
Then, in the method,
if (queueList == null)
{
QueueSelection selection = new QueueSelection();
queueList =selection.initQueueCollection();
}
Related
I'm facing a weird behavior in my Java code using List.
The code is very simple, I have a List of Object called AccessRequest which comes from a database and I'm using this first List to create a new one but with a filter to select only a few objects.
Here is the code :
private void updateCommentIfNeeded() {
List<AccessRequest> accessRequestList = getAllRequest();
List<AccessRequest> commentsList = getCommentsListProcessedManually(accessRequestList);
}
public List<AccessRequest> getCommentsListProcessedManually(List<AccessRequest> accessRequests) {
accessRequests.removeIf(ar -> !ar.getComment().equals("To be processed manually"));
if (accessRequests.size() != 0) {
SQLServerConnection sqlServerConnection = new SQLServerConnection(sqlServerUrl);
accessRequests.removeIf(ar -> !sqlServerConnection.emailExists(ar.getEmail()));
}
return accessRequests;
}
I'm supposed to get a second List only containing the objects that has their comments to To be processed manually, which I do. But the weird part is that the first List also takes the value of the second as if I wrote accessRequestList = commentsList but there is no such thing and I'm using local variable.
Ex :
I have 3 objects in my first List, but only one containing the required comment
Both list ends with containing the only objects containing the comment
I'm kind of lost here if anyone has an idea !
Your method getCommentsListProcessedManually modifies the list you're passing. I believe you're operating under the assumption that passing the list as a parameter somehow creates a copy of the list, whereas what is actually happening is that a reference to the list is passed by value.
There are several ways to solve this, but the easiest is to simply create a copy of your input list at the start of your method:
public List<AccessRequest> getCommentsListProcessedManually(List<AccessRequest> input) {
List<AccessRequest> accessRequests = new ArrayList<>(input);
accessRequests.removeIf(ar -> !ar.getComment().equals("To be processed manually"));
if (accessRequests.size() != 0) {
SQLServerConnection sqlServerConnection = new SQLServerConnection(sqlServerUrl);
accessRequests.removeIf(ar -> !sqlServerConnection.emailExists(ar.getEmail()));
}
return accessRequests;
}
You could also use the Stream API for this (using the filter operation), but that's quite a bit trickier in this situation.
You are passing a reference of the list to the method getCommentsListProcessedManually.
So accessRequestList and the one passed as a parameter are the same, hence any operation done to the list is done to the same list.
You can create a copy of the list before passing it as a parameter:
List<AccessRequest> newList = new ArrayList<AccessRequest>(accessRequestList);
public boolean isConnectedTo(Suspect aSuspect){
boolean flag = false;
Registry tempRegistry = new Registry();
ArrayList<Communication> TempComms = new ArrayList<Communication>(tempRegistry.GetComms());
for(Communication comms : TempComms) {
System.out.println("here");
for(String PhoneNums : phoneNumbers){
if(PhoneNums.equals(comms.GetTransmitter())) {
for(String numbers : aSuspect.getNumbersList()) {
if(numbers.equals(comms.GetReceiver()))
flag = true;
}
}
}
}
return flag;
}
So I am trying to create a program that among other things, it will search two ArrayLists(TempComs and phoneNumbers) and it will return true or false whether a string in the first is the same with a string in the second or not. I create the new ArrayList TempComms with the method tempRegistry.GetComms(). GetComms() is a method in another class, (class Registry) and has just a return communications; command, communications is an ArrayList in the class Registry.(The ArrayList phoneNumbers is an arrayList of the class the code is into.) So normally with with
ArrayList<Communication> TempComms = new ArrayList<Communication>(tempRegistry.GetComms());
the ArrayList TempComms must be the same with ArrayList communication that exists in the other class. But I figured out that for some reason the problem is in TempComms, because the first for is never running(For that reason I used System.out.println("here"); but it never printed). I searched and tried a lot to find the solution of this problem of my own, but I didn't manage to make some progress, so I would be grateful if someone who knows where's the problem or what I do wrong tell me about it. Thanks anyway.
You are creating a new instance of the Registry which contains a list (comms).
Registry tempRegistry = new Registry();
Then you are trying to get that comm list by calling tempRegistry.GetComms() .
Unless you are populating this communication list in the constructor Registry() (not only instantiating, you should add some entries as well),
that list will be empty when for loop is called.
(Because you are clearly NOT populating it after creating the instance tempRegistry and before calling the for loop.
ArrayList<Communication> TempComms = new ArrayList<Communication>(tempRegistry.GetComms());
for(Communication comms : TempComms) {
Therefore, the TempComms list is also an empty list. Which is why the inside code of the for loop is not executing.
BlockingQueue<ServiceSync>bq=new LinkedBlockingDeque<ServiceSync>();
ServiceSync s=new ServiceSync();
s.setService(OperationsConst.CODE, commonUtil.DOWNLOAD, true,null );
bq.add(s);
//s=new ServiceSync();
s.setService(OperationsConst.LOGIN, commonUtil.DOWNLOAD, true,null );
bq.add(s);
tmp=new TempThread(bq, context);
tmp.setBlockingQueue(bq);
Here, I added 2 objects but every time, only the second object is added in the queue.
You have used the same reference s after changing the value. Please create another object of ServiceSync, set the value you want and add to queue as show below.
BlockingQueue<ServiceSync> bq = new LinkedBlockingDeque<ServiceSync>();
ServiceSync s1 = new ServiceSync();
s1.setService(OperationsConst.CODE, commonUtil.DOWNLOAD, true, null);
bq.add(s1);
ServiceSync s2 = new ServiceSync();
s2.setService(OperationsConst.LOGIN, commonUtil.DOWNLOAD, true, null);
bq.add(s2);
Currently you are adding s to the queue, change the value you added and add it second time. So you end up with a queue that has the same object there twice. Either uncomment the s=new ServiceSync(), or (better) create a new variable of type ServiceSync and add it to the queue.
I'm trying to add multiple records to a list and iterate. But its displaying only latest records added
Here is my code
List<ExportBean> exportBeans = new ArrayList<ExportBean>();
ExportBean exportBean = new ExportBean();
exportBean.setBooleanValue(true);
exportBean.setKeyValue("PRE_APPROVED_OFFER");
exportBean.setStringValue("111");
exportBeans.add(exportBean);
exportBean.setBooleanValue(true);
exportBean.setKeyValue("PRE_APPROVED_OFFER1");
exportBean.setStringValue("222");
exportBeans.add(exportBean);
getLopRefNo(exportBeans);
when I iterate it
def getLopRefNo = {
exportBeans->
println "in function ${exportBeans}"
}
It shows only
in function [ExportMessagingBean{stringValue='222', keyValue='PRE_APPROVED_OFFER1', exportBoolean=true}, ExportMessagingBean{stringValue='222', keyValue='PRE_APPROVED_OFFER1', exportBoolean=true}]
It doesnt show the first record added. Is it missing anything?
The problem has nothing to do with Groovy. In your code, you are not actually adding two objects, you are adding one object and modifying it.
List<ExportBean> exportBeans = new ArrayList<ExportBean>();
ExportBean exportBean = new ExportBean();
exportBean.setBooleanValue(true);
exportBean.setKeyValue("PRE_APPROVED_OFFER");
exportBean.setStringValue("111");
exportBeans.add(exportBean); // add object to list
exportBean.setBooleanValue(true);
exportBean.setKeyValue("PRE_APPROVED_OFFER1");
exportBean.setStringValue("222");
exportBeans.add(exportBean); // this time, the same reference is "added". This does not result in an addition (in fact, "add" will return false here
getLopRefNo(exportBeans);
You are calling add with an object that is already present in the list so it has no effect. What you should do is create another instance of ExportBean, like this:
List<ExportBean> exportBeans = new ArrayList<ExportBean>();
ExportBean exportBean = new ExportBean();
exportBean.setBooleanValue(true);
exportBean.setKeyValue("PRE_APPROVED_OFFER");
exportBean.setStringValue("111");
exportBeans.add(exportBean); // add object to list
exportBean = new ExportBean(); //create new instance of ExportBean
exportBean.setBooleanValue(true);
exportBean.setKeyValue("PRE_APPROVED_OFFER1");
exportBean.setStringValue("222");
exportBeans.add(exportBean); // this new instance will be correctly added
getLopRefNo(exportBeans);
You only have one ExportBean object in your code (you only said new ExportBean() once) so you have added the same object to the list twice. Your second set of calls to the set methods on the bean just updates your existing object rather than creating a new one.
This is my code snippet:
public NaturalNumberTuple toSet()
{
int newTuple[] = new int[tuple.length];
boolean checkIfYouHadToRemoveSomething = false;
for(int i : newTuple){
newTuple[i] = tuple[i];
}
for(int i : newTuple){
for(int j : tuple){
if(newTuple[i] == tuple[j]){
NaturalNumberTuple placeholderTuple = remove(tuple[j]);
newTuple[i] = tuple[j];
checkIfYouHadToRemoveSomething = true;
}
}
}
if(checkIfYouHadToRemoveSomething){
return placeholderTuple;//Problem
} else {
return new NaturalNumberTuple(tuple);
}
}
The method is returning a new NaturalNumberTuple without the given Number (here tuple[j]).
My toSet() method should give me the same Array as I'm giving to it but with only one occurrence per number.
My problem is in the line marked with (//Problem).
The Problem is that placeholderTuple is not defined as a variable. I know it isn't, but if I write at the beginning of my method:
NaturalNumberTuple placeholderTuple;
and at the line where I originally defined my placeholderTuple:
placeholderTuple = remove(..);
it gives me an error that placeholderTuple may not been initialized yet.
I know why I'm getting those errors but I really don't know how to fix that.
If anyone is trying to optimize my code with ArrayLists, please don't because I'm not allowed to use them (not sure if they would help here but at other code snippets they would).
At the start of your method, write :
NaturalNumberTuple placeholderTuple = null;
This will keep this variable visible till the end of the method, and initialize it to a default value.
Then, inside the loop yo change :
NaturalNumberTuple placeholderTuple = remove(tuple[j]);
to
placeholderTuple = remove(tuple[j]);
Declare and initialize it in the begining of the code as:
NaturalNumberTuple placeholderTuple = null;
And in your loop, just initialize it without redefining like placeholderTuple = remove(tuple[j]); and it should work.
I think your code will always return the last entry of newTuple which is similar to tuple, so it doesnt makes sense to me. If you just want to remove very first match, you could do without two loop like:
placeholderTuple = remove(tuple[0]);