Why my 2nd while loop in not executing? - java

public void compare(ArrayList list_old, ArrayList list_new) {
try {
Iterator<User> iterator_old = list_old.iterator();
Iterator<User> iterator_new = list_new.iterator();
//Check New User Is Added
while (iterator_new.hasNext()) {
Log.i("Test", "inside!");
User user_new = iterator_new.next();
boolean NEW = true;
while (iterator_old.hasNext() && NEW) {
User user_old = iterator_old.next();
if (user_new.getUsername().equals(user_old.getUsername())) {
NEW = false;
}
}
if (NEW) {
generateNotification(getApplicationContext(), user_new.getUsername() + " has been added.");
}
}
//Check User Is Removed
while (iterator_old.hasNext()) {
Log.i("Test", "inside");
User user_old = iterator_old.next();
boolean NEW = true;
while (iterator_new.hasNext() && NEW) {
User user_new = iterator_new.next();
if (user_old.getUsername().equals(user_new.getUsername())) {
NEW = false;
}
}
if (NEW) {
generateNotification(getApplicationContext(), user_old.getUsername() + " has been removed.");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
In this function I am comparing my old list with my new list.
The first while loop check, is any new user added and second while loop check, is any user is removed.
When I am running this application only my first while loop execute and it does not execute second while loop.
I checked with Log.i("Test", "inside!"); and I found it does not come inside my second while loop.
Please help

You need to re-initialize the iterator,
public void compare(ArrayList list_old, ArrayList list_new) {
try {
Iterator<User> iterator_old;
Iterator<User> iterator_new = list_new.iterator();
//Check New User Is Added
while (iterator_new.hasNext()) {
Log.i("Test", "inside!");
User user_new = iterator_new.next();
boolean NEW = true;
iterator_old = list_old.iterator();
while (iterator_old.hasNext() && NEW) {
User user_old = iterator_old.next();
if (user_new.getUsername().equals(user_old.getUsername())) {
NEW = false;
}
}
if (NEW) {
generateNotification(getApplicationContext(), user_new.getUsername() + " has been added.");
}
}
//initialize again
iterator_old = list_old.iterator();
//Check User Is Removed
while (iterator_old.hasNext()) {
Log.i("Test", "inside");
User user_old = iterator_old.next();
boolean NEW = true;
iterator_new = list_new.iterator();
while (iterator_new.hasNext() && NEW) {
User user_new = iterator_new.next();
if (user_old.getUsername().equals(user_new.getUsername())) {
NEW = false;
}
}
if (NEW) {
generateNotification(getApplicationContext(), user_old.getUsername() + " has been removed.");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

You're not resetting your iterators anywhere, so I don't think any of that code is working as you want it to. Your code would probably work and be much more readable if you used a for-each loop, which all Iterable classes support. This will avoid the need to create and reset iterators entirely.
for (User newUser : list_new) {
for (User oldUser : list_old)
// Compare
}
for (User oldUser : list_old) {
for (User newUser : list_new)
// Compare
}

Related

Race condition in multiple instance in kubernates

Hi i have a race condition in given method i have 2 instances in kubernates and checking in redis
public void method(GuestDTO guestDTO) {
String executeName = "addingGuestToCache" + guestDTO.getUser();
if (!redisService.checkExecute(executeName)) {
redisService.startExecute(executeName);
OpenGuestDTO openGuestDTO = new OpenGuestDTO();
RMap<String, List<OpenGuestDTO>> openGuestDTOList = redisService.getOpenGuestDTOList();
List<OpenGuestDTO> userGuestList = openGuestDTOList.get(guestDTO.getUser());
if (userGuestList == null) {
userGuestList = Collections.synchronizedList(new ArrayList<OpenGuestDTO>());
}
for (OpenGuestDTO guestDTO1 : userGuestList) {
if (guestDTO1.getGuestName().equalsIgnoreCase(guestDTO.getGuestName())) {
redisService.deleteExecute(executeName);
return;
}
}
openGuestDTOList.add(openGuestDTO);
openGuestDTOList.fastPut(guestDTO.getUser(), userGuestList);
redisService.deleteExecute(executeName);
}else{
method(guestDTO);
}
}

Check purchase with google billing at startup

I'm currently using the Google Billing API to check at startup of my android app if the user has bought the premium package.
I'm using the queryPurchases() method to parse the purchases. I would like to ask if this is the correct way to check a purchase without using a server. I've read about the 200000 API limit - is there a better way to implement this?
This is the current flutter method that I run at every startup:
Future<void> initBillingPlatform() async {
try {
await FlutterInappPurchase.instance.initConnection;
List<PurchasedItem> puchased = await FlutterInappPurchase.instance.getAvailablePurchases();
String result;
bool purchased = false;
for (int i = 0; i < puchased.length; i++) {
PurchasedItem item = puchased.elementAt(i);
if ((item.productId == "premium_features_developer" || item.productId == "premium_features") &&
item.purchaseStateAndroid != null &&
item.purchaseStateAndroid == 1) {
purchased = true;
if (!item.isAcknowledgedAndroid) {
result = await FlutterInappPurchase.instance.acknowledgePurchaseAndroid(item.purchaseToken);
print(result);
}
}
}
isPremium = purchased;
} on Exception catch (e) {
//Se arriva in errore il default è premium=false
print(e);
}
FlutterInappPurchase.instance.endConnection;
}
The method getAvailablePurchases() of this flutter package runs the following code:
final String type = call.argument("type");
final JSONArray items = new JSONArray();
Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(type.equals("subs") ? BillingClient.SkuType.SUBS : BillingClient.SkuType.INAPP);
final List<Purchase> purchases = purchasesResult.getPurchasesList();
try {
if (purchases != null) {
for (Purchase purchase : purchases) {
JSONObject item = new JSONObject();
item.put("productId", purchase.getSku());
item.put("transactionId", purchase.getOrderId());
item.put("transactionDate", purchase.getPurchaseTime());
item.put("transactionReceipt", purchase.getOriginalJson());
item.put("orderId", purchase.getOrderId());
item.put("purchaseToken", purchase.getPurchaseToken());
item.put("developerPayloadAndroid", purchase.getDeveloperPayload());
item.put("signatureAndroid", purchase.getSignature());
item.put("purchaseStateAndroid", purchase.getPurchaseState());
if (type.equals(BillingClient.SkuType.INAPP)) {
item.put("isAcknowledgedAndroid", purchase.isAcknowledged());
} else if (type.equals(BillingClient.SkuType.SUBS)) {
item.put("autoRenewingAndroid", purchase.isAutoRenewing());
}
items.put(item);
}
result.success(items.toString());
}
} catch (JSONException je) {
result.error(call.method, je.getMessage(), je.getLocalizedMessage());
} catch (FlutterException fe) {
result.error(call.method, fe.getMessage(), fe.getLocalizedMessage());
}

How to get two different types of object from(same) arraylist and then store them in two different tables in database

I have two different classes – Lecturer and SecurityGuard – stored in ArrayList<EmployeeData>. Now I want to store them in database but I am getting NullPointerException. Code for saving them to database.
btnSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Iterator iter = empData.iterator();
while (iter.hasNext()) {
Lecturer tempLec = new Lecturer(0,"",0,0);
Object obj = iter.next();
if (obj.getClass().equals(tempLec.getClass())) {
LecturerManager.addLecturerToDB((Lecturer) obj);
}
else {
SecurityGuardManager.addSecGaurdToDB((SecurityGuard) obj);
}
}
});
}
Code for Manager Function
public static Boolean addSecGaurdToDB(SecurityGuard sg) {
Boolean isADDED = false;
String query = String.format("INSERT INTO SecurityGuards (EmployeeID,Name,HourlyRate,AreaAssigned) VALUES('%s','%s','%s','%s')",sg.getId(),sg.getName(),sg.getHourlyRate(),sg.getAreaAssigned());
try {
isADDED = statement.execute(query);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return isADDED;
}

Issues Serializing an ArrayList object containing other ArrayList objects

So I'm Serializing an ArrayList of ArrayLists essentially but I'm running into an issue. To be honest I'm still pretty new to Java, I've tried so many different methods to fix this as well as searched relentlessly on this site and have not been successful. I know that the way I word things may be hard to follow along or is confusing so I'll post my code here to see. Sorry in advance for all the code. SuperUsers has an arraylist of LoginInfo, PasswordKeeper has an Arraylist of SuperUsers, and the SuperUser arraylist gets serialized in PasswordKeeper. but any changes made to the LoginInfo arraylist do not save and i cannot figure out why. If anyone can help I would really Appreciate it. Thanks
public class PasswordKeeper{
private ArrayList<SuperUser> users;
private static Scanner keyboard = new Scanner(System.in);
public PasswordKeeper() {
users = new ArrayList();
}
public void login() {
try {
// reads in SuperUser arraylist
get();
} catch (EOFException a) {
System.out.println("You are the First User!");
} catch (IOException b) {
System.out.println(b);
} catch (ClassNotFoundException c) {
System.out.println(c);
}
boolean loopDisplay = true;
while (loopDisplay) {
existingUser = keyboard.next();
existingPass = keyboard.next();
SuperUser temp = new SuperUser(existingUser, existingPass);
System.out.println();
if (users.contains(temp)) {
// viewing superUser method
temp.display();
//saves after method call is over
try {
System.out.println("Saving.");
save(users);
} catch (IOException e) {
System.out.println(e);
}
}
}
//This happens if there is a new user
if(answer == 2){
SuperUser tempNew = null;
boolean cont = true;
String newUser;
String pass;
while(cont){
newUser = keyboard.nextLine();
System.out.println();
//System.out.println(users.size());
tempNew = new SuperUser(newUser, pass);
if(passValid(pass) == true){
if(makeSure(tempNew) == true){
System.out.println("Login Created!");
tempNew = new SuperUser(newUser, pass);
//actually being added to the arraylist
users.add(tempNew);
cont = false;
}
}
}
//SuperUser.display method
tempNew.display();
try{
System.out.println("Saving.");
save(users);
}catch(IOException e){
System.out.println(e);
}
}
}
}
//makeSure and passValid methods
public boolean makeSure(SuperUser user){
if(users.contains(user)){
return false;
}
return true;
}
public boolean passValid(String pass){
boolean passes = false;
String upper = "(.*[A-Z].*)";
String lower = "(.*[a-z].*)";
String numbers = "(.*[0-9].*)";
String special = "(.*[,~,!,#,#,$,%,^,&,*,(,),-,_,=,+,[,{,],},|,;,:,<,>,/,?].*$)";
if((pass.length()>15) || (pass.length() < 8)){
System.out.println("Entry must contain over 8 characters\n" +
"and less than 15.");
passes = false;
}if(!pass.matches(upper) || !pass.matches(lower)){
System.out.println("Entry must contain at least one uppercase and lowercase");
passes = false;
}if(!pass.matches(numbers)){
System.out.println("Password should contain atleast one number.");
passes = false;
}if(!pass.matches(special)){
System.out.println("Password should contain atleast one special character");
passes = false;
}else{
passes = true;
}
return passes;
//serializable methods
public void save(ArrayList<SuperUser> obj) throws IOException {
File file = new File("userInformation.dat");
FileOutputStream fileOut = new FileOutputStream(file, false);
BufferedOutputStream buffedOutput = new BufferedOutputStream(fileOut);
ObjectOutputStream out = new ObjectOutputStream(buffedOutput);
out.writeObject(obj);
out.close();
fileOut.close();
}
public ArrayList<SuperUser> get() throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("userInformation.dat");
BufferedInputStream buffedInput = new BufferedInputStream(fileIn);
ObjectInputStream in = new ObjectInputStream(buffedInput);
users = (ArrayList<SuperUser>) in.readObject();
in.close();
fileIn.close();
return users;
}
public class SuperUser implements Serializable {
private String userName;
private String password;
private static Scanner keyboard = new Scanner(System.in);
private ArrayList<LoginInfo> info = new ArrayList();
public SuperUser(String name, String pass) {
userName = name;
password = pass;
}
public String getUser() {
return userName;
}
public void display() {
String next = keyboard.next();
//want to add data to LoginInfo arraylist
if (next.equalsIgnoreCase("add")) {
add();
} else if (next.equalsIgnoreCase("delete")) {
delete();
} else if (numberCheck(next)) {
int choice = (int) Integer.parseInt(next) - 1;
edit(choice);
//!!!! this: after doing this i lose whatever data i added
//to the LoginInfo arraylist, right after this the
//SuperUser arraylist gets saved. but the added data to
//loginInfo does not
} else if (next.equalsIgnoreCase("logout")) {
System.out.println(info.size());
}
}
public boolean numberCheck(String in) {
try {
Integer.parseInt(in);
} catch (NumberFormatException e) {
return false;
}
return true;
}
//method to add to the Arraylist
public void add() {
System.out.println("What is the website name?:");
String trash = keyboard.nextLine();
String webName = keyboard.nextLine();
System.out.println("The Username?:");
String webUsername = keyboard.nextLine();
System.out.println("The Password?:");
String webPass = keyboard.nextLine();
info.add(new LoginInfo(webUsername, webPass, webName));
System.out.println(info.size());
//method goes back to display
display();
}
}
}
Your problem is here
SuperUser temp = new SuperUser(existingUser, existingPass);
System.out.println();
if (users.contains(temp)) {
// viewing superUser method
temp.display();
You create a temporary object which with the username and password.
Your 'users.contains()' method returns true because '.equals()' is based on the username, however the 'temp' object is a different instance to that in the list.
So when you call 'temp.display()' it is not calling on an object in the list, so no data changes will save.
You need to find the existing object from the list for that user. I would suggest that you swap your list for a map keyed on username.
You have a list named users. Once you created new SuperUser instance (temp), you are checking that it belongs to this list (users.contains(temp), which is false of course - from where it will occur there?). If it have belonged, the method display would be called, which in turn would add LoginInfo to that SuperUser (add() call), but I bet in reality it doesn't happened.
Also, I see where you read from users (check whether new SuperUser instances belong there), I see where you overwrite it (during desealization) but I don't see adding any instance to there, which makes me think that it is always empty.
Are you sure that SuperUser contains any LoginInfo in its array list?

Using Command pattern for undo and redo in ArrayLists

So I have a program where you can log in and add/remove friends to and from the friends arraylist. Also I can like a certain thing and that thing will be stored into the likes arraylist. I'm asked to make undo and redo options for whichever action I do.
So I want to add apple as a friend. After that when I select the undo option, I can undo that action so apple wouldn't be my friend. How I can approach this with a Command Pattern when the input is whatever name or word I inputted to store into the friends arraylist?
I did some research and found that using a command pattern could be my best bet since this has to be done under the Facebook Class I already have. I'm assuming I'll have to use two different stacks, but I'm getting a bit lost in the topic.
I decided to add parts of what I have so that I can get a bit more help on what I need to do and what my program does.
In the driver program
Facebook facebook1 = new Facebook();
if (userInput == 6)
{
System.out.println("Login");
String operand1 = getOperand("What is the Username? ");
String operand2 = getOperand("What is the Password? ");
System.out.println("Enter a friend to be added. ");
String operand3 = getOperand("What is the Username? ");
facebook1.friend(operand3);
}
if (userInput == 7)
{
System.out.println("Login");
String operand1 = getOperand("What is the Username? ");
String operand2 = getOperand("What is the Password? ");
System.out.println("Enter a friend to be removed. ");
String operand3 = getOperand("What is the Username? ");
facebook1.defriend(operand3);
}
if (userInput == 12)
{
System.out.println("Login");
String operand1 = getOperand("What is the Password? ");
facebook1.undo();
}
if (userInput == 13)
{
System.out.println("Login");
String operand1 = getOperand("What is the Password? ");
facebook1.redo();
}
In the Facebook Class
ArrayList<FacebookUser> recommendedFriends = new ArrayList<FacebookUser>();
void friend(String newFriend)
{
boolean positiveChecker = false;
for (int i = 0; i < recommendedFriends.size(); i++)
{
if (recommendedFriends.get(i).toString().equalsIgnoreCase(newFriend))
{
System.out.println("Error: This friend already exists.");
positiveChecker = true;
}
}
if (positiveChecker == false)
{
FacebookUser friend = new FacebookUser(newFriend, newFriend );
recommendedFriends.add(friend);
System.out.println(friend + " is now your friend.");
}
positiveChecker = false;
}
void defriend(String formerFriend)
{
boolean positiveChecker = false;
for (int i = 0; i < recommendedFriends.size(); i++)
{
if (recommendedFriends.get(i).toString().equalsIgnoreCase(formerFriend))
{
recommendedFriends.remove(i);
System.out.println(formerFriend + " has been removed from your friends list.");
positiveChecker = true;
}
if (recommendedFriends.size() == (i + 1) && recommendedFriends.get(i).toString() != formerFriend
&& positiveChecker == false)
{
System.out.println("Error: There is no friend with this username.");
}
}
positiveChecker = false;
}
public interface Command
{
public void undo();
public void redo();
}
When you undo 2 things then do a completely new action, you need to "forget" the "redo history" and replace it with the new command, right?
For example...
Add Friend Jim
Add Friend Bill
Add Friend Jill
Remove Jim
Undo
Undo
State should be "Jim" and "Bill".
So you only really need one list and a pointer to the current "command", for example...
// Note: NOT thread safe!
public class CommandStack {
private List<Command> commands = Collections.emptyList();
private int nextPointer = 0;
public void doCommand(Command command) {
List<Command> newList = new ArrayList<>(nextPointer + 1)
for(int k = 0; k < nextPointer; k++) {
newList.add(commands.get(k));
}
newList.add(command);
commands = newList;
nextPointer++;
// Do the command here, or return it to whatever called this to be done, or maybe it has already been done by now or something
// (I can only guess on what your code currently looks like...)
command.execute();
}
public boolean canUndo() {
return nextPointer > 0;
}
public void undo() {
if(canUndo()) {
nextPointer--;
Command commandToUndo = commands.get(nextPointer);
// Undo the command, or return it to whatever called this to be undone, or something
command.undo();
} else {
throw new IllegalStateExcpetion("Cannot undo");
}
}
public boolean canRedo() {
return nextPointer < commands.size();
}
public void redo() {
if(canRedo()) {
commandToDo = commands.get(nextPointer);
nextPointer++;
// Do the command, or return it to whatever called this to be re-done, or something
commandToDo.execute();
} else {
throw new IllegalStateException("Cannot redo");
}
}
}
If I had...
interface Command { /* execute / undo etc */ }
public class AddFriendCommand implements Command {
private String friendName;
// ... other fields, constructor / getters etc ...
public void execute() {
// Actually do it...
System.out.println("Added friend " + name);
}
public void undo() {
// Undo it...
System.out.println("Removed friend " + name);
}
}
public class RemoveFriendCommand implements Command {
private String friendName;
// ... other fields, constructor / getters etc ...
public void execute() {
// Actually do it, maybe throw exception if friend does not exist?
// (that would have to be a runtime exception unless you want the interface's method to throw stuff);
System.out.println("Removed friend " + name);
}
public void undo() {
// Undo it...
System.out.println("Added friend " + name);
}
}
You could repeat the sequence above using...
CommandStack stack = new CommandStack();
stack.doCommand(new AddFriendCommand("Jim"));
stack.doCommand(new AddFriendCommand("Bill"));
stack.doCommand(new AddFriendCommand("Jill"));
stack.doCommand(new RemoveFreindCommand("Jim"));
stack.undo();
stack.undo();
If you now did a new command (via doCommand) it would forget that you ever added "Jill" or removed "Jim", but instead would now remember the new command and the rest of the command history that was not undone.
Hope this helps.
You are misunderstanding how the command pattern works. You want to have a separate List of your Commands, where each instance of Command represents an action.
So you would want to have something like:
List<Command> actionStack;
and then have stuff like
public class AddCommand implements Command {
private final void List<FacebookUser> userList;
private final void FacebookUser newUser;
public AddCommand(List<FacebookUser> userList, FacebookUser newUser) {
this.userList = userList;
this.newUser = newUser;
}
#Override
public void undo() {
userList.remove(newUser);
}
#Override
public void redo() {
userList.add(newUser);
}
}

Categories