how to put second time exist is 2 or so on? - java

how to add if my data first time exist, value will put 1, if the data already exist into hashmap, need put 2 and so on.
below is my coding:
public ArrayList<String> processJson(JSONObject json) {
HashMap<String, Integer> hm = new HashMap<String, Integer>();
ArrayList<String> output = new ArrayList<>();
for (int i = 0; i < hits.length(); i++) {
// to make sure funny/stupid/illogical resp back from ES is caught and ignored!
try {
JSONArray tag = item.getJSONArray("tag");
System.out.println("tag" + hm.entrySet());
if (source.equalsIgnoreCase("trkd")) {
for (int j = 0; j < tag.length(); j++) {
if (j == 0) {
if (!hm.containsKey(tag.toString(0))) {
hm.put(tag.getString(0), 1);
} else {
hm.put(tag.getString(0), new Integer(j + 1));
}
}
}
}
if (hm.containsValue(1)) {
output.add(out);
} else {
output.add(out);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return output;
}
if the value equal to 1, output just add.
but now, my hashmap all is value 1, how to do?

You are doing the compare on
if (!hm.containsKey(tag.toString(0))) {
but updating with
hm.put(tag.getString(j), 1);
so j != 0
I guess the contains should also be using j
Edit
As #Adi points out
Plus, the check the condition 'j==0', this is unnecessary and prevents you from processing beyond first tag.

Instead of a HashMap, you should use a Multimap. Google Guava provides one.

Lots of weird things going on in your code.
Pretty sure tag.toString(int) and tag.getString(int) are not equivalent. I bet you only wanted to use getString
Why is everything happening in j==0 clause? Your loop would effectively only be doing useful stuff only once.
Were you actually trying to code something like this?
if (!hm.containsKey(tag.getString(j))) {
hm.put(tag.getString(j), 1);
} else {
hm.put(tag.getString(j), hm.get(tag.getString(j)+1);
}
The following code doesn't require an if-else since you're doing the same thing in both cases.
if (hm.containsValue(1)) {
output.add(out);
} else {
output.add(out);
}
Can be replaced with:
output.add(out)
I don't think you're explaining very well what you need to do. From whatever I could gather using my code from #3 should get you exactly what you want.

Related

Error handling for a while loop

I need help with this scenario where I need to find a string from a pagination table wherein each page contains 50 items. My code below works fine, only problem is that when it cannot find the data my while loop sometimes keep running indefinitely and does not fail but sometimes it does! What can I do so that it will always return an error after reaching a number of loops?
public int inboxLocateLoan(String expName, String name) throws Throwable {
//Locate Loan element in SharePoint table
report.setFailedResult("Loan element is not found");
int loanRow;
try {
boolean loansearch = true;
while (loansearch) {
List < WebElement > rowElem = getWebElements(getAEDriver(), "xpath", sRow);
for (int i = 1; i <= rowElem.size(); i++) {
String actualLoanName = driver.findElement(By.xpath("//*[#id='onetidDoclibViewTbl0']/tbody[2]/tr[" + i + "]/td[3]")).getText();
// String actualLoanNumber = driver.findElement(By.xpath("//*[#id='onetidDoclibViewTbl0']/tbody[2]/tr["+i+"]/td[5]")).getText();
loanRow = i;
if (actualLoanName.equals(expName)) {
loansearch = false;
return loanRow;
}
if (actualLoanName.equals(name)) {
click(getAEDriver(), "xpath", "//*[#class='ms-pivotControl-surfacedOpt-selected']", "Refresh");
loansearch = true;
} else {
if (i == 50) {
click(getAEDriver(), "xpath", "//*[#id='pagingWPQ2next']/a", "Next Page");
} else {
loansearch = true;
}
}
}
}
}
Initialize the romElem outside the for, and then use it to toggle your flag. If you reached your max rowElemen and you didn't find what you were looking for, it is safe then to assume that the value will be false.
Also, what is the purpose of the while? you could remove it completely, it is usually a bad idea to mix a while and a for. I don´t see the point in doing so in this case.

Comparing With an ArrayList

My program calls for being able to delete a name and number from a phone book. I have gotten the deleting to work but it only deletes the index from the ArrayList that the text box corresponds to. I need to be able to delete both the name and the number from their respective arraylists by entering it into either texbox. Sorry if there is another answer to this i guess i dont really know how to word it correctly. My code is below.
ArrayList<String> Names = new ArrayList<String>();
ArrayList<String> Numbers = new ArrayList<String>();
if(e.getSource() == DeleteBtn)
{
if (NameTxt.getText() != null)
{
for( int i=0; i<= NamesList.size(); i++)
{
if(NamesList.contains(NameTxt.getText()))
{
NamesList.remove(i);
System.out.println(NamesList.size());
}
}
}
if (PhoneTxt.getText() != null)
{
for( int i=0; i<= NumbersList.size(); i++)
{
if(NumbersList.contains(PhoneTxt.getText()))
{
NumbersList.remove(i);
System.out.println(NumbersList.size());
}
}
}
}
If you HAVE to use ArrayLists then you might consider using an ArrayList of pairs.
You can create your own class, say PhoneBookEntry.
class PhoneBookEntry {
String _name;
String _phone;
// etc...
}
ArrayList<PhoneBookEntry>
Consider using a HashMap instead of the ArrayLists.
HashMap<String, String> numbersAndNames = new HashMap<String, String>();
numbersAndNames.put("John", "123 456 789");
If I were you, I would reconsider my logic. I'm going to try and avoid posting code for you to keep from giving you the answer/doing the work for you but...
I only see you modifying the NamesList variable. You aren't modifying the Names or Numbers ArrayList variables.
I would put your 'contains if statement' some place else. Your checking to see if NameList contains NameText a bunch of times. I don't see why you would need to check it more than once.
If you want to get smart, you can do away with the array completely and just use the getIndex() method to some effect in java...which gets the index corresponding to NameText (I'm being vague here deliberately, so think about what I'm saying).
You can use a HashMap if you want, but it's not necessary.
Per suggestion of using an additional class to track the name/number combo.
ArrayList contacts = new ArrayList();
if(e.getSource() == DeleteBtn) {
if (NameTxt.getText() != null) {
for( int i=0; i<= contacts.size(); i++) {
if(contacts.getName().contains(NameTxt.getText())) {
contacts.remove(i);
System.out.println(contacts.size());
}
}
}
public class PhoneContact {
private String name;
private String number;
/*
Getters and Setters
*/
}
First of all, NumbersList.contains(PhoneTxt.getText()) returns if PhoneTxt.getText() is anywhere in the list.
What you want to check is the NumbersList.get(i).equals(PhoneTxt.getText()) note that i used equals() instead of == operator
my friend actually found the answer, he simply added the other ArrayList(i), thank you to all who posted answers, as they gave me food for thought, just thought the logic of the answer would not work but i was proven wrong, here is the code for anyone interested.
if(e.getSource() == DeleteBtn)
{
if (NameTxt.getText() != null)
{
for( int i=0; i<= NamesList.size(); i++)
{
if(NamesList.contains(NameTxt.getText()))
{
NamesList.remove(i);
NamesList.remove(i);
System.out.println(NamesList.size());
System.out.println(NumbersList.size());
}
}
}
if (PhoneTxt.getText() != null)
{
for( int i=0; i<= NumbersList.size(); i++)
{
if(NumbersList.contains(PhoneTxt.getText()))
{
NumbersList.remove(i);
NamesList.remove(i);
System.out.println(NamesList.size());
System.out.println(NumbersList.size());
}
}
}
}

Continue keyword in recursion

I have come across the below code while searching some answers.
public static void recurse(Scanner in, HashMap<String, Integer> oldMap) {
HashMap<String, Integer> map = null;
if (oldMap == null)
map = new HashMap<String, Integer>();
else
map = new HashMap<String, Integer>(oldMap);
while (in.hasNext) {
String s = in.nextLine();
if (s.startsWith("[")) {
recurse(in, map);
continue;
}
if (s.startsWith("]")) {
break;
}
String[] split = s.split(" ");
if (s.startsWith("print")) {
System.out.println(map.containsKey(split[1]) ? map.get(split[1]) : 0);
continue;
}
int x = 0;
try {
x = Integer.parse(split[1]);
} catch (Exception e) {
x = map.containsKey(split[1]) ? map.get(split[1]) : 0;
}
map.put(split[0], x);
}
}
Can somebody please explain me , why the person has used continue just after recursive call. It seems to be that the continue will not be processed because each time the recursion call will be processed.
It's true that the recursive call will be processed — but then, eventually, the recursive call will return. (Unless it either raises an exception or enters an infinite loop, that is.) After the recursive call returns, the continue statement is executed.
It might help you to play with a simpler example of recursion:
public void printOneToN(int n) {
if(n > 1) {
printOneToN(n - 1);
}
System.out.println(n);
}
As you can see by running (say) printOneToN(10), after each recursive call, control returns to its caller. A recursive call does not replace its caller.
continue has nothing to do with the recursive call; its effect is to skip the rest of the contents of the while loop and go straight back to in.hasNext().

Looping my list so that runs through and combines the whole list

I am in a beginning class for programming and try to combine 2 lists to make one list, putting the new list in numerical order. The part I am having trouble with is, allowing the code to loop, repeating the steps so that it runs through the total original loops to complete the final list which is a combination of all the numbers from the original lists. Any guidance for the loop would be appreciated. Thank you.
import inClass.list.EmptyListException;
import inClass.list.List;
public class InitialLists {
public static void main(String[] args) {
List<Integer> intObject1 = new List<Integer>();{
intObject1.insertAtFront(25);
intObject1.insertAtFront(19);
intObject1.insertAtFront(3);
intObject1.print();}
List<Integer> intObject2 = new List<Integer>();{
intObject2.insertAtFront(120);
intObject2.insertAtFront(1);
intObject2.print();}
List<Integer> combinedList = new List<Integer>();
int object1 = intObject1.removeFromBack();
int object2 = intObject2.removeFromBack();
while(intObject1.removeFromBack() != null && intObject2.removeFromBack() != null){
try {
{
if (intObject1.removeFromBack() > intObject2.removeFromBack()) {
combinedList.insertAtFront(object2);
intObject1.insertAtBack(object1);
}
else if (intObject2.removeFromBack() < intObject1.removeFromBack()) {
combinedList.insertAtFront(object1);
intObject2.insertAtBack(object2);
}
else if (intObject1.removeFromBack() == intObject2.removeFromBack()) {
combinedList.insertAtFront(object1);
}
}
combinedList.print();
object1 = intObject1.removeFromBack();
object2 = intObject2.removeFromBack();
} // end try
catch (EmptyListException emptyListException) {
emptyListException.printStackTrace();
} // end catch
} //end while
} // end main
}// end class
What about:
List<Integer> combinedList = new ArrayList<Integer>();
combinedList.addAll(intObject1);
combinedList.addAll(intObject2);
Collections.sort(combinedList);
Or am I missing something?
To merge two files / lists / streams you need a loop that looks a bit like this
WHILE NOT FINISHED
GET SMALLEST VALUE FROM INPUTS
APPEND SMALLEST VALUE TO OUTPUT
So how will you know that you are finished?
How will you get the smallest of the next item in each list?
The code I have written above is called pseudocode; it is a way of describing the steps of an algorithm. Keep expanding each step until you have pseudocode that you can implement in your chosen language, in this case Java.
Hope that helps ...
I guess your problem is because of possible uneven size of two lists. Try putting while condition as below:
Integer object1 = intObject1.removeFromBack();
Integer object2 = intObject2.removeFromBack();
while(object1 != null || object2!= null){
if(object1 ==null){
//safe to assume object2 is not null as both not null together (that is the termination condition)
combinedList.insertAtFront(object2);
}else if(object2 ==null){
//safe to assume object1 is not null as both not null together (that is the termination condition)
combinedList.insertAtFront(object1);
}else{
//put you normal condition of handling object1 and object2 being not null
if (object1.intValue() > object2.removeFromBack()) {
combinedList.insertAtFront(object2);
intObject1.insertAtBack(object1);
}
else if (object2.intValue() < object1.intValue()) {
combinedList.insertAtFront(object1);
intObject2.insertAtBack(object2);
}
else if (object1.intValue() == object2.intValue()) {
combinedList.insertAtFront(object1);
}
}
object1 = null;
object2 = null;
try{
object1 = intObject1.removeFromBack();
}catch (EmptyListException emptyListException) {
//do nothing
} // end catch
try{
object2 = intObject2.removeFromBack();
}catch (EmptyListException emptyListException) {
//do nothing
} // end catch
}
Also please note: There are better way of doing the merge of two sorted list elements. This approach is advised in light of your little known custom List class.

concurrentexception i don't understand where it's the error

I receive this exception
Exception in thread "Thread-3" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at ServerMultiThread.run(ServerMultiThread.java:89)
at java.lang.Thread.run(Thread.java:680)
from this code:
synchronized(itemsList)
{
if(itemsList.isEmpty())
{
item.initCounter();
itemsList.add(item);
pw.println("It's the first time you connect to server!");
}
else
{
for(ItemClient itm : itemsList)
{
if(itm.equals(item))
{
int value = itm.getCounter();
value++;
itm.setCounter(value);
pw.println(itm.getCounter());
}
else
{
item.initCounter();
itemsList.add(item);
pw.println("It's the first time you connect to server!");
}
}
}
}
the row 89 corresponds to this for(ItemClient itm : itemsList). Why I receive this error?
You are changing the LinkedList content inside the for-each loop. The implementation of the LinkedList iterator checks on the next call to next() if the list has changed and throws the exception (sad I know ...).
The enhanced for loop is used to iterate over the given set of values, but during iteration you are modifying the contents of the same, that's why you getting that error, instead use a normal for loop to do your stuff for this thing.
Regards
Sadly, there is no easy way around it. As the others have said, you cannot modify a collection inside this kind of loop. Your other option is to use a normal for loop. However, accessing a LinkedList by index like:
for(int i = 0; i < list.size(); i++) {
list.get(i);
}
takes O(N) time for each item, because the linked list needs to be traversed from the beginning each time.
If the linked list is not essential to your algorithm, I suggest you to use an ArrayList instead and change your code as follows:
for(int i = 0; i < itemsList.size(); i++) {
itm = itemsList.get(i);
if(itm.equals(item)) {
int value = itm.getCounter();
value++;
itm.setCounter(value);
pw.println(itm.getCounter());
} else {
item.initCounter();
itemsList.add(item);
pw.println("It's the first time you connect to server!");
}
}
This will not throw the exception, but it's still not a nice piece of code because you are adding to the list while iterating and that is never a good idea.
I hope you had patience to read so far!
My final suggestion for you is to hold a temporary list of elements that you need to add and append them to the initial list at the end of the loop. This way you can keep all your original code and the LinkedList:
LinkedList<ItemClient> tempList = new LinkedList<ItemClient>();
for(ItemClient itm: itemsList) {
itm = itemsList.get(i);
if(itm.equals(item)) {
int value = itm.getCounter();
value++;
itm.setCounter(value);
pw.println(itm.getCounter());
} else {
item.initCounter();
tempList.add(item);
pw.println("It's the first time you connect to server!");
}
}
itemsList.addAll(tempList);

Categories

Resources