Build Logic Tree like the where clause in sql - java

I want to build a Logic Tree in Java which contains the conditions that could be used
for database insertions.
for example:
Node tree = input0.eq(3).and(input1.eq(1).or(input2.greaterThan(5)));
could be converted to:
WHERE input0=3 AND (input1 = 1 OR input2 > 5)
Since a Node could be a logical expression like and,or etc. as well as a Leaf with data, I thought a parent Node class and two child classes, would be ideal. But I have no idea how to handle nested expressions. I already read a few similiar questions here, but they weren't really specific enough.
public class Node {
public Long id;
public Node parent;
public List<Node> children;
}
public class LogicalNode extends Node {
LogicType logicType;
public LogicalNode () {
super();
}
getter and setter...
}
public class LeafNode extends Node {
Object input;
public LeafNode () {
super();
}
getter and setter...
}
public enum LogicType
{
AND("and"),
OR("or"),
NOT("not"),
EQ("="),
GREATER_THAN(">"),
LESSER_THAN("<");
private String name;
LogicType (String name) {
this.name= name;
}
public String getName() {
return name;
}
}

To get you started, try something similar to this:
public abstract class Node {
abstract void toSql();
Node eq(Node other) {
return new LogicalNode(LogicalType.EQ, this, other);
}
...
}
public class LeafNode extends Node {
LeafNode(int value) {
this.value = value;
}
String toSql() {
return this.value.toString();
}
}
public class LogicalNode extends Node {
LogicalNode(LogicalType type, Node left, Node right) {
this.logicalType = type;
this.left = left;
this.right = right;
}
String toSql() {
return String.format(
"(%s) %s (%s)",
this.left.toSql(),
this.logicalType.getName(),
this.right.toSql()
);
}
}
The key here is that the LogicalNode is constructed using two other Nodes, but it doesn't concern itself with whether or not they are LeafNodes or LogicalNodes. All LogicalNode knows is that it has two things that can be converted to a string using toSql.

Related

Java Vector: Each element contains three objects. How to operate based on the value of one of them?

For example, I have vector(object1, object2, price). How can I print elements where price > 100?
All the tutorials and documents (concerning operating in such way) I have seen only handle vectors where each element contains only one object.
So how can I get a handle on one specific object inside element? Or is this even possible?
A side question: what are those called? That is, if a single element is comprised of several items, what are those items called? Like in databases, a record is comprised of fields. Hard to google stuff you do not know the name of.
Main:
import java.util.Vector;
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String type;
String location;
double value;
System.out.print("type->");
type=sc.nextLine();
System.out.print("location->");
location=sc.nextLine();
Property prop=new Property(type,location);
System.out.print("value->");
value=sc.nextDouble();
InsuranceInfo insu=new InsuranceInfo(prop,value);
container.addInsuranceInfo(insu);
}
InsInfoContainer class:
public class InsInfoContainer {
private Vector<InsuranceInfo> container;
public InsInfoContainer() {
container = new Vector<>(3, 1);
}
public void addInsuranceInfo(InsuranceInfo insu) {
container.addElement(insu);
}
public void print() {
Iterator<InsuranceInfo> iter = container.iterator();
while (iter.hasNext()) {System.out.println(iter.next());}
}
InsuranceInfo class:
public class InsuranceInfo {
public InsuranceInfo(Property prop, double value) {
this.prop = prop;
this.value = value;
}
private Property prop;
private double value;
public Property getProp() {return prop;}
public void setProp(Property prop) {this.prop = prop;}
public double getValue() {return value;}
public void setValue(double value) {this.value= value;}
}
Property class:
public class Property {
private String type;
private String location;
public Property(final String type, final String location) {
this.type = type;
this.location = location;
}
public String getType() {return this.type;}
public void setType(final String type) {this.type = type;}
public String getLocation() {return this.location;}
public void setLocation(final String sijainti) {this.location = location;}
}
You have a container to store your InsuranceInfo:
private Vector<InsuranceInfo> container;
Your container is called Collection
Your InsuranceInfo instances inside your container are called element
Your "items" inside InsuranceInfo (Property, value) are called property or field of element
To iterate over your container collection, the usual ways are using for loop or foreach loop:
public void print() {
for (InsuranceInfo element: container) {
if (element.getValue() > 100) { // Here is your condition to filter elements
// Process your elements here
}
}
}
You can also use Iterator, Stream to do that.

Java how to return a generic type that extends an interface

I have an interface named IDedObject and I am making a linkedlist class that uses generics that extend the IDedObject interface. In the linkedList class, I have a function that tries to find a given item based on it's data, and then returns that item. I am getting an error that says
Incompatible types. Required: AnyType. Found: IDedObject
This is what my code looks like:
Interface:
public interface IDedObject {
public int getID();
public void printID();
}
LinkedList:
public class singlyLinkedList<AnyType extends IDedObject> {
public Node<AnyType> endMarker;
public Node<AnyType> beginMarker;
AnyType findID(int ID){
Node curNode = beginMarker;
while(curNode.getNext() != endMarker){
if (curNode.getData().getID() == ID){
return curNode.getData();
}
}
return null;
}
}
class Node<AnyType extends IDedObject>{
public Node(AnyType d, Node<AnyType> n){
data = d;
next = n;
}
public Node getNext(){
return next;
}
public AnyType getData() {
return data;
}
public AnyType data;
private Node<AnyType> next;
private int theSize;
}
I appreciate any help with this. It's for a homework assignment, so i'm required to use a generic the extends IDedObject.
Thanks.
I fixed the problem by changing
Node curNode = beginMarker;
to
Node<AnyType> curNode = beginMarker;
in the findID function in the LinkedList class. Not sure how I missed that.

HashMap change Values Object

I have a set with String and i want to create hash map with String key and Node Object value.
and this is my code
Set<String> cities = new HashSet<>();
Map<String, Node> allCity = new HashMap<>();
Iterator<String> c = cities.iterator();
while(c.hasNext()){
String name = c.next();
Node cit = new Node(name);
allCity.put(name, cit);
}
my problem is when i read first from c iterator and correctly make new object and put it to hash map but when second object was create in my hash map the previous object value was change like this
first read
key = "New York"
Value = Node (and the value of node is New York)
second read
Key = "Los Angles"
Value = Node (and the value of node is Los Angles)
and my first read Value with New York key was change to Los Angles.
myNode class
public class Node{
private static String city;
private static double pathCost;
private ArrayList<Edge> neighbours;
private Node parent;
public Node(String cityName){
city = cityName;
neighbours = new ArrayList<>();
}
public static String getValue() {
return city;
}
public static void setValue(String city) {
Node.city = city;
}
public static double getPathCost() {
return pathCost;
}
public static void setPathCost(double pathCost) {
Node.pathCost = pathCost;
}
public static String getCity() {
return city;
}
public static void setCity(String city) {
Node.city = city;
}
public ArrayList<Edge> getNeighbours() {
return neighbours;
}
public void setNeighbours(ArrayList<Edge> neighbours) {
this.neighbours = neighbours;
}
public void addNeighbours(Edge n){
this.neighbours.add(n);
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
#Override
public String toString() {
return city;
}
}
Please help me.
That's because you made the city (and pathCost) fields static. A static field belongs to the class, not to a specific instance of this class. Each node has a specific city, so you want to mek the city field an instance field, and not a static field.
Read the Java tutorial about class members.
The city member in your Node class is static. This means all the Nodes share the same city, and when one instance updates it (e.g., in the constructor), the change applies for all of them.
To resolve this issue, you could change city to be an instance member:
public class Node{
private String city;
...
Without looking thoroughly there is a major mistake here:
private static String city;
city is node (i.e. instance) data and should not be static.
Since it is static in your case, all nodes share one value for city, which most probably isn't what you want. The same applies to pathCost.

Java Generic type identification

This is my class structure.
public class Node<T> {
private T value;
public Node(T val) {
this.value = val;
}
public T evaluate() {
return value;
};
}
T can be Integer, Double, Date, Long or String.
Now, is there anyway I can get to know exactly what that type T is? Thanks.
You can invoke getClass() method on that generic variable and find out the class. Basically generics are erased at run-time, so an unbounded generic is nothing but java.lang.Object. So you can invoke all the method supported by Object class on that generic variable
At run-time, getClass() on generic object will return the actual class which was used to substitute the generic
For example
public class Node<T> {
private T value;
public Node(T val) {
Class<?> clazz = val.getClass();
checkType(clazz);
this.value = val;
}
public T evaluate() {
return value;
};
private void checkType(Class<?> c) {
if(c.getName().equals(Integer.class.getName())) {
//...
}
}
}
Much easier, use instanceof.
public class Node<T> {
private T value;
public Node(T val) {
checkType(val);
this.value = val;
}
public T evaluate() {
return value;
};
private void checkType(T val) {
if(val instanceof Integer) {
//...
}
}
}
Though there is already an accepted answer, I think it may be good to add one more answer:
As mentioned by #BaileyS, there is no way to get info of T in a place without an instance of T.
The solution greatly depends on why you want T, how you are using it. Normally, if we need the type of T for the logic (e.g. creating a new instance of T), it is usually done by providing the Class instance.
For example, you can make your Node class be:
public class Node<T> {
private T value;
private Class<T> valueType;
public Node(T val, Class<T> valueType) {
this.value = val;
this.valueType = valueType;
}
//.....
}
If you know that your node will store only Number you could restrict it.
public class Node<T extends Number> {
private final T value;
public Node(T val) {
this.value = val;
}
public T evaluate() {
return value;
};
public Class<? extends Number> type() {
return value.getClass();
}
}

Java Inheritance Maximize reuse

In following example, TreeNode is the superclass and BinaryNode is subclass.
public class TreeNode {
private int data;
private TreeNode parent;
private List<TreeNode> children;
TreeNode() {
this.data = 0;
this.parent = null;
this.children = new ArrayList<TreeNode>();
}
}
In subclass, every node has only two children.
I write as following.
How should I write the member fields and constructor to best use the superclass, yet keep the structure right?
public class BinaryNode extends TreeNode {
// int data;
// BinaryNode parent;
List<BinaryNode> children;
BinaryNode() {
super();
children = new ArrayList<BinaryNode>(2);
}
}
in constructor BinaryNode(), super() is called, what's the impact on children?
What's more, if the subclass has specific rules on some fields, like only two children in this sample, how to write the constructors in superclass and subclass to maximize reuse?
if I have the following method isLeaf() in superclass and don't write it in subclass.
When I try to use it with a subclass instance, would it function correctly?
public boolean isLeaf() {
if(this.children == null)
return true;
else
return false;
}
You mark the attributes protected in the superclass and the subclass should have access to them:
public class TreeNode {
protected int data;
protected TreeNode parent;
protected List<TreeNode> children;
...
public boolean isLeaf() {
if(this.children == null)
return true;
else
return false;
}
}

Categories