Java - TreeMap do not retrieves the key - java

I've topped with a problem I can not understand exactly what's happening here.
I operate with a TreeMap<Custom_class, TreeMap<Custom_class, Integer>>
Here is the fragment of code:
TreeMap<Coordenada, Integer> helper_tree;
boolean newLine = false;
for (Linea l : this.lineas) {
int helper = 0;
newLine = true;
Coordenada helper_co = null;
for (Coordenada c : l.getNodosLinea()) {
helper++;
if (!c.getEsEstacion() && !c.getEsCruce()) continue;
if (newLine) { map.putIfAbsent(c, new TreeMap<>()); helper_co = c; helper = 0; newLine = false; continue; }
helper_tree = new TreeMap<>();
helper_tree.put(helper_co, helper * 200);
map.put(c, helper_tree);
map.get(helper_co).put(c, helper * 200);
helper_co = c;
helper = 0;
}
}
In the execution the highlighted line fails, getting 0 entry for a key:
debug mode in intellij
And this is TreeMap structure:
TreeMap structure
I dont understand why in fails at .get(key) when the key Coordenada(12,2) is present. All before works just fine.
Coordenada class
public class Coordenada implements Comparable<Coordenada>{
private int[] coordenada = new int[2];
private boolean esEstacion = false;
private boolean esCruce = false;
public Coordenada(int[] coordenada){
this.coordenada[0] = coordenada[0];
this.coordenada[1] = coordenada[1];
}
public void setCoordenada(int[] coordenada) {
this.coordenada = coordenada;
}
public int[] getCoordenada() {
return coordenada;
}
public void switchEstacion(){
this.esEstacion = !this.esEstacion;
}
public void switchCruce() { this.esCruce = !this.esCruce; }
public boolean getEsEstacion() {
return this.esEstacion;
}
public boolean getEsCruce() { return this.esCruce; }
#Override
public boolean equals(Object coord){
Coordenada coordTemp = (Coordenada) coord;
if (this.coordenada[0] != coordTemp.coordenada[0])
return false;
if (this.coordenada[1] != coordTemp.coordenada[1])
return false;
return true;
}
#Override
public int compareTo(Coordenada o) {
if (this.coordenada[0] > o.coordenada[0] )
return 1;
if (this.coordenada[1] > o.coordenada[1] )
return 1;
if (this.coordenada[0] < o.coordenada[0])
return -1;
if (this.coordenada[1] < o.coordenada[1])
return -1;
return 0;
}
#Override
public String toString() {
return "(" + coordenada[0] + ", " + coordenada[1] + ")";
}
}
Inserts perfectly Coordenada(12,2) and modifies previous helper_co = Coordenada(10,2)
debugger variables
Thanks for any help!

Look at your compareTo function
(0,1) compareTo (1,0) returns 1
(1,0) compareTo (0,1) returns 1
It's ambiguous.

Related

How to merge two alike items within the ArrayList?

So, I have 1 superclass DessertItem. Which has 4 subclasses Candy, Cookie, Ice Cream, Sundae. The Sundae class extends the Ice Cream class. Superclass is an abstract class. I also have a separate class which does not belong to the superclass, but in the same package - Order. There is another class - DessertShop, where the main is located.
Candy, Cookie classes implement SameItem<> generic class. The generic interface SameItem<> class looks like this:
public interface SameItem<T> {
public boolean isSameAs(T other);
}
The Candy, Cookie classes have this method:
#Override
public boolean isSameAs(Candy other) {
if(this.getName() == other.getName() && this.getPricePerPound() == other.getPricePerPound()) {
return true;
}
else {
return false;
}
}
And something similar, but for the cookie class.
All the subclasses have these methods :
default constructor,
public Cookie(String n, int q, double p) {
super(n);
super.setPackaging("Box");
cookieQty = q;
pricePerDozen = p;
}
public int getCookieQty() {
return cookieQty;
}
public double getPricePerDozen() {
return pricePerDozen;
}
public void setCookieQty(int q) {
cookieQty = q;
}
public void setToppingPricePricePerDozen(double p) {
pricePerDozen = p;
}
#Override
public double calculateCost() {
double cookieCost = cookieQty * (pricePerDozen/12);
return cookieCost;
}
and toString() method
So, what my program does is gets the input from the User, asks the name of the dessert, asks the quantity, or the quantity according to the dessert, ask the unit price. Asks the payment method. And then prints the receipt. This how the Order class looks like:
import java.util.ArrayList;
import java.util.List;
public class Order extends implements Payable{
//attributes
PayType payMethod;
private ArrayList<DessertItem> OrderArray;
//Constructor
public Order() {
OrderArray = new ArrayList<>();
payMethod = PayType.CASH;
}
//methods
public ArrayList<DessertItem> getOrderList(){
return OrderArray;
}// end of getOrderList
public ArrayList<DessertItem> Add(DessertItem addDesert){
enter code here
OrderArray.add(addDesert);
/* for(DessertItem i : getOrderList()) {
if(i instanceof Candy) {
for(DessertItem j : getOrderList()) {
if(j instanceof Candy) {
if(((Candy) i).isSameAs((Candy) j)) {
*/
//this is what I have tried so far, but I am lost
}
}
}
} else if(i instanceof Cookie) {
for (DessertItem j : getOrderList()) {
if(((Cookie) i).isSameAs((Cookie)j)) {
OrderArray.add(j);
} else {
OrderArray.add(i);
}
}
}
}
return OrderArray;
}// end of Add
public int itemCount(){
int counted = OrderArray.size();
return counted;
}//end of itemCount
public double orderCost() {
double orderResult = 0;
for(int i=0; i<OrderArray.size(); i++) {
orderResult = orderResult + OrderArray.get(i).calculateCost();
}
return orderResult;
}
public double orderTax() {
double taxResult = 0;
for(int i = 0; i<OrderArray.size(); i++) {
taxResult = taxResult + OrderArray.get(i).calculateTax();
}
return taxResult;
}
public double orderTotal() {
double ordertotal = orderTax() + orderCost();
return ordertotal;
}
#Override
public PayType getType() {
// TODO Auto-generated method stub
return payMethod;
}
#Override
public void setPayType(PayType p) {
payMethod = p;
}
public String toString() {
String finalOutput = "";
finalOutput += "------------------------Receipt--------------------------\n";
for(int i = 0; i < OrderArray.size(); i++) {
finalOutput = finalOutput + OrderArray.get(i).toString();
}
finalOutput += "--------------------------------------------------\n";
String line2 = "Total Number of items in order: " + itemCount() + "\n";
String line3 = String.format("Order Subtotals:\t\t\t\t $%-6.2f", orderCost());
String line4 = String.format("[Tax: $%.2f]\n", orderTax());
String line5 = String.format("\nOrder Total:\t\t\t\t\t $%-6.2f\n", orderTotal());
String outputVar = String.format("%s\n%s%s%17s", line2, line3, line4, line5);
String ending = "----------------------------------------------------";
String payType = String.format("\nPaid for with: %s", payMethod.name());
return finalOutput + outputVar + ending + payType;
}
So, my question is, how can I combine like items into one item?

Implementing a Doubly Linked List from a Sorted Array Bag (Data Structures)

it's my first time ever posting on StackOverFlow, because I'm truly desperate right now. I couldn't find an answer for my problem anywhere, so long story short, I have some kind of project for my Data Structures course. The project had 2 parts. The first part was implementing a Sorted Array Bag/ Sorted Collection for some problem. We are using java.
The second part is where I do actually have a lot of problems. So the main idea is implementing a doubly-linked list from the sorted-array bag/ sorted collection and in a way that I would just switch sorted array bag with doubly-linked list in my main and everything should work the way it was working before.
The main thing about the SortedArrayBag is as far as I understand using a Comparator when you declare the SortedArrayBag in your main, and it looks like this:
SortedBag<Grupe> al = new SortedArrayBag<>(new ComparatorVot());
al.add(new Grupe("gr1", 5));
al.add(new Grupe("gr2", 7));
The sorted collection/sorted array bag was implemented by my teacher because there is no such data structure in Java, here is her implementation:
public class SortedArrayBag<T> implements SortedBag<T> {
private ArrayList<T> elemente;
private Comparator<T> relatie;
public SortedArrayBag(Comparator<T> rel) {
this.elemente = new ArrayList<>();
this.relatie = rel;
}
public void add(T elem) {
int index = 0;
boolean added = false;
while (index < this.elemente.size() && added == false) {
T currentElem = this.elemente.get(index);
if (relatie.compare(currentElem, elem) < 0) {
index++;
} else {
this.elemente.add(index, elem);
added = true;
}
}
if (!added) {
this.elemente.add(elem);
}
}
public void remove(T elem) {
boolean removed = this.elemente.remove(elem);
}
public int size() {
return this.elemente.size();
}
public boolean search(T elem) {
return this.elemente.contains(elem);
}
public Iterator<T> iterator() {
return this.elemente.iterator();
}
}
And the SortedBag interface looks like this
public interface SortedBag<T> {
public void add(T elem);
public void remove(T elem);
public int size();
public boolean search(T elem);
public Iterator<T> iterator();
}
Also in case it helps, the comparator looks like this:
public class ComparatorVot implements Comparator<Grupe> {
public int compare(Grupe o1, Grupe o2) {
Grupe gr1 = (Grupe) o1;
Grupe gr2 = (Grupe) o2;
if (gr1.getNrPersoane() / 2 + 1 == gr2.getNrPersoane() / 2 + 1) {
return 0;
} else if (gr1.getNrPersoane() / 2 + 1 > gr2.getNrPersoane() / 2 + 1) {
return 1;
} else {
return -1;
}
}
}
So, I tried my best implementing doublyLinkedList using a SortedArrayBag, this is what I did, also if it helps making my code more clear, prim=first, ultim=last, urmator=next, anterior=previous
import java.util.Iterator;
public class LDI {
private Nod prim;
private Nod ultim;
//private int lungime;
public LDI() {
this.prim = null;
this.ultim = null;
//this.lungime = 0;
}
public class Nod {
private int elem;
private int frecventa;
private Nod urmator;
private Nod anterior;
public Nod(int e, int f) {
this.elem = e;
this.frecventa = f;
this.urmator = null;
this.anterior = null;
}
}
public void add(int elem, int frecventa) {
Nod nodNou = new Nod(elem, frecventa);
nodNou.elem = elem;
nodNou.frecventa = frecventa;
if (prim == null) {
this.prim = nodNou;
this.ultim = nodNou;
} else if (frecventa <= prim.frecventa) {
nodNou.urmator = prim;
this.prim.anterior = nodNou;
this.prim = nodNou;
} else if (frecventa >= prim.frecventa) {
nodNou.anterior = prim;
for (; nodNou.anterior.urmator != null; nodNou.anterior = nodNou.anterior.urmator) {
if (nodNou.anterior.urmator.frecventa > frecventa)
break;
}
nodNou.urmator = nodNou.anterior.urmator;
if (nodNou.anterior.urmator != null) {
nodNou.anterior.urmator.anterior = nodNou;
}
nodNou.anterior.urmator = nodNou;
nodNou.anterior = nodNou.anterior;
}
}
public void remove() {
if (this.prim != null) {
if (this.prim == this.ultim) {
this.prim = null;
this.ultim = null;
} else
this.prim = this.prim.urmator;
this.prim.anterior = null;
}
}
public int size() {
int count = 0;
for (Nod nodNou = prim; nodNou != null; nodNou = nodNou.urmator)
count++;
return count;
}
public class MyIterator {
private Nod curent;
public MyIterator() {
this.curent = prim;
}
public void urmator() {
this.curent = this.curent.urmator;
}
public int getElem() {
return this.curent.elem;
}
public boolean valid() {
if (this.curent != null) {
return true;
} else {
return false;
}
}
}
public Iterator iterator() {
return new MyIterator();
}
}
The thing is, it doesn't work, I have no idea how to make my data structure able to receive the Comparator I used and also the Iterator doesn't work. If you have any idea how to make this work, please do help me.

Exception in thread "main" java.lang.NullPointerException virtual stack class

I am trying to use this class to evaluate postfix expressions and when testing it am thrown this exception at line 32 where the virtual stack should push.
public class PostfixEval
{
private IntStack s;
public PostfixEval()
{
IntStack s = new IntStack();
}
public boolean isInteger(String s)
{
int i = 0;
boolean isDigit = true;
while(i < s.length() && isDigit)
{
isDigit = s.charAt(i) >= '0' && s.charAt(i) <= '9';
i++;
}
return isDigit;
}
public int eval(String e)
{
String[] tokens = e.split("\\s+");
for(int i=0; i<tokens.length; i++)
{
if(isInteger(tokens[i]))
{
s.push(Integer.parseInt(tokens[i]));
}
else
{
int a,b,c;
b = s.pop();
a = s.pop();
c = 0;
char d = tokens[i].charAt(0);
if(d == '+')
{
c = a + b;
}
else if(d == '-')
{
c = a - b;
}
else if(d == '*')
{
c = a*b;
}
else if(d == '/')
{
c = a/b;
}
else if(d == '%')
{
c = a%b;
}
else
{
System.out.println("Error");
System.exit(0);
}
s.push(c);
}
}
return s.peek();
}
}
I have used jgrasp to see what Integer.parseInt(tokens[i])) evaluates to and confirm it is a number from the split string. When trying to push a number that I type into the paramater of the push method it works, so why do I get null exception when using the PostfixEval to push?
Here is my stack class.
public class IntStack implements StackIntADT
{
// fields
private int[] stk;
private int sp;
// constructors
public IntStack()
{
sp = -1;
stk = new int[10];
}
public IntStack( int s )
{
sp = -1;
stk = new int[s];
}
// stack class methods
public void push(int element)
{
if(!isFull())
{
sp++;
stk[sp]=element;
}
else
{
System.out.println("Element" + element);
System.exit(0);
}
}
public int pop()
{
int rv = 0;
if(!isEmpty())
{
rv = stk[sp--];
}
else
{
System.out.println(rv);
System.exit(0);
}
return rv;
}
public int peek()
{
return stk[sp];
}
public boolean isEmpty()
{
return sp==-1;
}
public boolean isFull()
{
return sp==stk.length-1;
}
public int size()
{
return stk.length;
}
public String toString()
{
String s = "";
for(int x=0;x<10;x++)
{
s = s + " " + stk[x];
}
return s;
}
}
The constructor should not define a local s variable (which hides the member variable with the same name). The member variable is never assigned a value.
Change the constructor to this:
public PostfixEval() {
s = new IntStack();
}

ArrayList comparison

I have an ArrayList made out of classes objects .The class has several String fields . In some classes
some fields that are the same must be removed from the ArrayList .
The field from the class that I need to check is sorted_participants which is set to be the same in some objects.
This is my Class:
public class Neo4jCompensation {
private String number_of_participants;
private String amount;
private String sorted_participants;
private String unsorted_participants;
private String href_pdf_compensation;
private String signed_by_all;
public Neo4jCompensation() {
this.number_of_participants = "";
this.amount = "";
this.sorted_participants = "";
this.unsorted_participants = "";
this.href_pdf_compensation = "";
this.signed_by_all = "";
}
public String getNumber_of_participants() {
return number_of_participants;
}
public void setNumber_of_participants(String number_of_participants) {
this.number_of_participants = number_of_participants;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getSorted_participants() {
return sorted_participants;
}
public void setSorted_participants(String sorted_participants) {
this.sorted_participants = sorted_participants;
}
public String getUnsorted_participants() {
return unsorted_participants;
}
public void setUnsorted_participants(String unsorted_participants) {
this.unsorted_participants = unsorted_participants;
}
public String getHref_pdf_compensation() {
return href_pdf_compensation;
}
public void setHref_pdf_compensation(String href_pdf_compensation) {
this.href_pdf_compensation = href_pdf_compensation;
}
public String getSigned_by_all() {
return signed_by_all;
}
public void setSigned_by_all(String signed_by_all) {
this.signed_by_all = signed_by_all;
}
}
So I have a first list filled with Classes:
ArrayList<Neo4jCompensation> results_list=new ArrayList<Neo4jCompensation>();
I thought that very good way to find the duplicates is to make a copy of a list , compare the two for the same class fields values and remove the duplicates .
This is how I find the duplicates
ArrayList<Neo4jCompensation> results_list1=new ArrayList<Neo4jCompensation>();
for(Neo4jCompensation pp:results_list)
{
Neo4jCompensation ss=new Neo4jCompensation();
ss.setAmount(pp.getAmount());
ss.setHref_pdf_compensation(pp.getHref_pdf_compensation());
ss.setNumber_of_participants(pp.getNumber_of_participants());
ss.setSigned_by_all(pp.getSigned_by_all());
ss.setSorted_participants(pp.getSorted_participants());
ss.setUnsorted_participants(pp.getUnsorted_participants());
results_list1.add(ss);
}
for (int i = 0; i < results_list.size(); i++) {
Neo4jCompensation kk=new Neo4jCompensation();
kk=results_list.get(i);
for (int j = 0; j < results_list1.size(); j++) {
Neo4jCompensation n2=new Neo4jCompensation();
n2=results_list1.get(j);
if(i!=j)
{
String prvi=kk.getSorted_participants().trim();
String drugi=n2.getSorted_participants().trim();
if(prvi.equals(drugi))
{
// results_list1.remove(j);
out.println("<p> Are equal su :"+i+" i "+j+"</p>");
}
}
}
}
Since I know that I can not loop and remove the elements from the ArrayList at the same
time i tried to use iterators like this ...
int one=0;
int two=0;
Iterator<Neo4jCompensation> it = results_list.iterator();
while (it.hasNext()) {
Neo4jCompensation kk=it.next();
Iterator<Neo4jCompensation> it1 = results_list1.iterator();
while (it1.hasNext()) {
Neo4jCompensation kk1=it1.next();
String oo=kk.getSorted_participants().trim();
String pp=kk1.getSorted_participants().trim();
if(one<two && oo.equals(pp))
{
it1.remove();
}
two++;
}
one++;
}
But it fails and gives me back nothing in ArrayList results_list1 - before removal with iterator it has in it the right elements . How to remove the objects from the array list that have the same field values as some other objects in the ArrayList .
Why not use .removeAll()
results_list1.removeAll(resultList);
This will require you to implement equals and hashcode within Neo4jCompensation
public class Neo4jCompensation {
//Omitted Code
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime
* result
+ ((number_of_participants == null) ? 0
: number_of_participants.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Neo4jCompensation other = (Neo4jCompensation) obj;
if (number_of_participants == null) {
if (other.number_of_participants != null)
return false;
} else if (!number_of_participants.equals(other.number_of_participants))
return false;
return true;
}
}
Another approach could be:
Overrride equals method in your Neo4jCompensation and check for the sorted_participants and return accordingly. Then use Set as a collection of your objects. Set does not allow duplicates and it uses equals to determine the equality.
for (int i = 0; i < results_list.size(); i++) {
Neo4jCompensation kk=new Neo4jCompensation();
kk=results_list.get(i);
for (int j = 0; j < results_list1.size(); j++) {
Neo4jCompensation n2=new Neo4jCompensation();
n2=results_list1.get(j);
if(results_list1.contains(kk) { results_list1.remove(j); }
}
But you may want to use a Set instead of a List or a data structure that maintains order, like a SortedMap, with a sentinel value.

Stack Overflow error adding an object in ArrayList of []

I get stack overflow error when I try to load(). I am trying to read PhoneBookEntry objects from a txt file. The txt file has a name and number which make up the PhoneBookEntry object.
Can you please let me know what I'm doing wrong?
package HashSet;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Scanner;
public class PhoneBook {
int capacity = 10;
private ArrayList<PhoneBookEntry>[] buckets;
public PhoneBook() {
this(10);
}
public PhoneBook(int size) {
capacity = size;
buckets = new ArrayList[size];
for (int i = 0; i < buckets.length; i++) {
buckets[i] = new ArrayList<PhoneBookEntry>();
}
}
public int getSize() {
int tot = 0;
for (ArrayList<PhoneBookEntry> x : buckets)
tot += x.size();
return tot;
}
public boolean add(PhoneBookEntry entry) {
if (contains(entry))
return false;
int x = Math.abs(entry.hashCode());
buckets[x % buckets.length].add(entry);
return true;
}
public void load()
{
InputStream is = getClass().getClassLoader().getResourceAsStream("phone.txt");
Scanner scan = new Scanner(is);
if (scan.hasNext())
add(new PhoneBookEntry(scan.next());
}
public void bucketSize() {
for (int i = 0; i < buckets.length; i++)
System.out.println(i + " " + buckets[i].size());
}
public boolean contains(PhoneBookEntry word) {
int x = Math.abs(word.hashCode());
return buckets[x % buckets.length].contains(word);
}
public int getCapacity() {
return capacity;
}
public static void main(String[] args) {
PhoneBook phone = new PhoneBook();
phone.load();
}
}
package HashSet;
import java.util.LinkedList;
import java.util.ListIterator;
public class PhoneBookEntry {
String n;
Integer nr;
LinkedList<PhoneBookEntry> list;
public PhoneBookEntry(String name, int number) {
list = new LinkedList<PhoneBookEntry>();
n = name;
nr = number;
list.add(new PhoneBookEntry(n, nr));
}
public String getN() {
return n;
}
public void setN(String n) {
this.n = n;
}
public Integer getNr() {
return nr;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((n == null) ? 0 : n.hashCode());
result = prime * result + ((nr == null) ? 0 : nr.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PhoneBookEntry other = (PhoneBookEntry) obj;
if (n == null) {
if (other.n != null)
return false;
} else if (!n.equals(other.n))
return false;
if (nr == null) {
if (other.nr != null)
return false;
} else if (!nr.equals(other.nr))
return false;
return true;
}
public void setNr(Integer nr) {
this.nr = nr;
}
#Override
public String toString() {
return n + " " + nr;
}
}
Every new phone book entry creates a new phone book entry that creates a new phone book entry that creates a new phome book entry, etc... ad infinitum. That is, until the stack space runs out.
You need to rethink your application data structure.
public PhoneBookEntry(String name, int number) {
list = new LinkedList<PhoneBookEntry>();
n = name;
nr = number;
list.add(new PhoneBookEntry(n, nr));
}
is causing an infinite recursion. You likely need a new class to put in the linked list (PhoneNumber or some such if a PhoneBookEntry can contain multiple names/numbers, otherwise ditch it.)

Categories

Resources