I am searching for a implementation/data structure for some categories and child categories that i have. I am thinking to use a search tree but not sure how to begin implementation.
Let me show you what the data looks like. its acutally coming to me as a json structure from back end but it looks like this:
[
{
"id": 94,
"category_name": "New In", //this is the category category_name
"description": "",
"children": [ //this is the category children which can also be a sub-category
{
"id": 322,
"category_name": "New Studio",
"description": "Chic, sophisticated and polished with a classic edge."
},
{
"id": 365,
"category_name": "New Soho",
"description": "Fresh, eclectic, and trendy. Oozes effortless cool."
},
{
"id": 809,
"category_name": "Summer Collection",
"description": "Your ultimate summer look"
}
]
},
{
"id": 12,
"category_name": "Clothes",
"description": "",
"children": [
{
"id": 22,
"category_name": "All Clothes",
"description": ""
},
{
"id": 63,
"category_name": "Tops",
"description": "",
"children": [
{
"id": 5,
"category_name": "All Tops",
"description": ""
}
]
},
{
"id": 641,
"category_name": "Accessories",
"description": "",
"children": [
{
"id": 61,
"category_name": "All Accessories",
"description": ""
},
{
"id": 622,
"category_name": "Jewelry",
"description": "",
"children": [ // here is an example of a child that is a sub-category also
{
"id": 52,
"category_name": "All Jewelry",
"description": ""
},
{
"id": 68,
"name": "Necklaces",
"description": ""
},
{
"id": 69,
"name": "Bracelets",
"description": ""
},
]
},
]
so if i had to draw this out it would look something like this:
So i want to be able to get path to anything. So for example if i want to search for Necklaces, then i want as well as getting a necklace to get the path of : Categories/Accessories/Jewelry/Necklaces
Is there a built in data structure for this ? i am coding in java. I suppose i also need the nodes sorted in some kind of order maybe A-Z.
so far i have this:
class Node{
String label;
List<Node> children;
}
but then how to search ? and is there a better data structure ? I do not want to iterate over all the nodes during a search, is there a way to sort the tree so i dont have to do that ? How i have it now i'd have to iterate over all the children. is there a way to maybe sort alphaetically perhaps or some kind of sort that would make the lookup faster ?
You need two things for this:
In your Node object, have a reference to the parent node as well:
class Node{
String label;
List<Node> children;
Node parent;
}
Create a HashMap that maps labels to the nodes:
HashMap<String, Node> labelsToNodes;
Then searching is done with the get() method in the HashMap. You get your category list by repeatedly getting the parent nodes. Let me know if you'd like the code for this and I'll add it (I'm short on time right now).
So far I do not know any Java built-in data structure that can handle what you are looking for. There are some tree implementations on github or this thread on stackoverflow will help you.
But if I understood you right, you are also interested to have a well performing search on your tree.
Sorting the tree does not completly solve this problem, because you still have to search every single subtree. Though it could significantly improve the search performance. But as far as I know there is no out of the box data structure in Java.
Another approach that came to my mind is to use a Map with your label and a reference to the according Node. However you would need a Tree where you can go from the leaves to the root node to get the full path and you have to take care of the duplicated information. E.g. if you delete a node, you also have to delete it in the map. If you also want to traversy the tree from the root you might build a bidirectional tree.
This is how my approach would look like:
class Node {
String label;
Node parent;
}
class Tree {
HashMap<String, List<Node>> tree;
}
It is a List<Node> if you have multiple times the same label name. E.g. if you have necklaces at jewlery and summer collection
I had a project this semester for searching on trees. I used different kind of algorithms. For example, BFS or DFS it depends on what you want and how you want to move on nodes in your tree. But, I prefer IDS(Iterative deepening depth-first search). To use this algorithm you can access this links.
it is better to have father instead of children cause it works better and you will not run out of memory.
clip in Youtube to show IDS
complete teaching about IDS
There are other good algorithms if you want you can just ask me.
You need to define a State class.
class State{
String name;
State father;
}
Related
Let's assume there's a map corresponding to the following structure:
{
"lists": [
{
"list": [
{
"letter": "a"
},
{
"letter": "b"
}
]
},
{
"list": [
{
"letter": "c"
},
{
"letter": "d"
}
]
}
]
}
There's an easy way to get all lists using SpEL (#root['lists']) or all letters of the first list ("#root['lists'][0]['list']") or the first letter of the first list ("#root['lists'][0]['list'][0]"). Also, there's a projection mechanism which allows using construction like "#root['lists'].![#this['list']]" to convert each item of lists to a result of the projection expression.
However, given all these possibilities, I still failed to come up with an expression allowing me to extract all letters from both lists. For the example above, I'd like to get
[
{
"letter": "a"
},
{
"letter": "b"
},
{
"letter": "c"
},
{
"letter": "d"
}
]
I tried to use the projection mechanism to achieve my goal but it didn't really help. The problem I see is that every time SpEL detects a list, it applies the projection expression to each element of the list so any structure of nested lists can't be changed this way.
The problem I solve can be easily solved using JsonPath, however, I assume I could get something wrong and didn't notice a way to achieve the same result using SpEL. I would be happy to listen to any ideas.
I am learning ShEx and using 'shexjava API' done by http://shexjava.lille.inria.fr/ for my project. I have schema, data graph and fixed shape map. When I validate using refine and recursive validation, I am getting ResultShapeMap but the reason and appInfo are null for NONCONFORMANT status. I do not understand why these two fields are null.
I have schema, dataGraph, shapeMap. This is code for validation.
ValidationAlgorithm vl = new RefineValidation(schema, dataGraph);
ResultShapeMap result = vl.validate(shapeMap);
Shape is,
{
"#context": "http://www.w3.org/ns/shex.jsonld",
"type": "Schema",
"shapes": [
{
"id": "http://example.com/ns#HouseShape",
"type": "Shape",
"expression": {
"type": "EachOf",
"expressions": [
{ "type": "TripleConstraint",
"predicate": "http://example.com/ns#number",
"valueExpr": { "type": "NodeConstraint",
"datatype": "http://www.w3.org/2001/XMLSchema#String"
}
},
{ "type": "TripleConstraint",
"predicate": "http://example.com/ns#size",
"valueExpr": { "type": "NodeConstraint",
"datatype": "http://www.w3.org/2001/XMLSchema#decimal"
}
}
]
}
}
]
}
Data is,
ex:House1 a ex:House ;
ex:number "11A" ;
ex:size 23 .
My Result is,
ResultShapeMap [
associations= [
ShapeAssociation [
nodeSelector=<example.com/ns#House>,
shapeSelector=<example.com/ns#HouseShape>,
status=NONCONFORMANT,
reason=null,
appInfo=null
]
]
]
I want to output the reason for not conforming. But it gives me null for that.
Could some one please help me.
The shexjava implementation currently does not support indicating a reason for failure.
This is because when a node does not satisfy a shape there may be several reasons.
If you want to learn ShEx, I would advise you to use ShapeDesigner
https://gitlab.inria.fr/jdusart/shexjapp/
which provides a graphical interface in which you can explore validation results.
In this particular case, it indicates that the validation fails because 23 is not a decimal (it's actually an integer) Screenshot of validation exploration result in ShapeDesigner
I do not know whether this is a bug, i.e. whether integrers should be considered to be also decimals in RDF.
I have a json like this and I use forEach to go over family
{
"people": {
"family": [
{
"id": "123",
"member": [
{
"id": "11",
"salary": false
},
{
"id": "12",
"salary": false
}
]
},
{
"id": "124",
"member": [
{
"id": "11",
"salary": false
},
{
"id": "12",
"salary": false
}
]
}
]
}
}
For instance, if I set the salary in true in the first member id 123, when i go through the second element of family (id 124), salary is also in true.
If I change something in the second one id 124, the first id 123 has the same value. It looks like every family element it's the same object but not sure how I can find out that and also how to fix it.
The code is really big, but basically I'm doing something like this:
.forEach(family -> {
family.getId() // I get 123 and then 124
family.getMember().forEach(member -> {
System.out.println(member.getSalary()) // Show false for id 123 but then for id 124, show true when i would be false at this point
member.setSalary(true);
Any idea? not sure what else I can do.... Thanks
Check if objects in member collection for 123 and 124 are different, have different reference. It sounds like those objects has the same reference in those two collections. Try maybe to override equals and hashCode.
so I am assuming the corrected result should be:
false
false
false
false
this statement member.setSalary(true); is shouldn't be affected
"member" is should be in separate object it shouldn't refer to same reference (pretty weird)
can u post the full block of code?
I have a mapping for two entities, ProfileGroup and User, where the User has a relationament #OneToMany to ProfileGroups;
The problem is that return of my requisitation, does not show the Foreign key fk_user of table ProfileGroup in the JSON requisitation for all ProfileGroups.
ProfileGroup
public class ProfileGroup {
...
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="fk_user_creator")
#JsonBackReference
private User userCreator;
...
User
public class User {
#OneToMany(mappedBy="userCreator")
#JsonManagedReference
private List<ProfileGroup> profileGroups;
The Resource class:
#GetMapping
public ResponseEntity<?> listAll(){
List<ProfileGroup> profileGroupsReturned = profileGroupRepository.findAll();
return !profileGroupsReturned.isEmpty() ? ResponseEntity.ok(profileGroupsReturned) : ResponseEntity.noContent().build();
And the result JSON: (DONT APPEAR THE FK_USER)
[
{
"id": 1,
"name": "Calango Careta",
"description": "Cadê? cadê? Nós somos a Orquestra Camaleônica do Calango Careta!!!!!!!!",
"founded": "2015-04-12",
"registered": "2018-11-14",
"active": true
},
{
"id": 2,
"name": "Tropicaos",
"description": "",
"founded": "2018-01-20",
"registered": "2018-11-14",
"active": true
},
{
"id": 3,
"name": "Capivara Brass Band",
"description": "",
"founded": "2016-08-24",
"registered": "2018-11-14",
"active": false
}
]
Any idea? What's wrong?
thank you!!
Problem
this is what JsonBackReference annotation does , though since you have bidirectional relation if you remove it you will end up with infinite loop when trying to serialize your objects.
Solution
If you really do not need to have bidirectional relation just get rid
of it by removeing on of the relations (either OnToMany or ManyToOne)
you can swap the BackReference to User but then you will not have the
group serialized in your user
you can use #JsonIgnore which will do the same as the previous
solution
you can start using separate DTO for serializing instead of
serializing your entity and there you can control the relation and
make sure you do not hit infinite serializing loop
you can use json property filters to ignore the property which will
cause the infinite loop, so forexample if you are serializing user ,
you can specify on profile property to ignore the user inside it so
you break the loop
I need to prepare JSON object like below, based on the user selected option dynamically. What is best approach to dynamically set value of "selected" key in JAVA. I have if-else and Switch in my mind but I am looking for better approach.
[{
"name": "By Distance",
"selected": "FALSE"
},
{
"name": "By Rating",
"selected": "TRUE"
},
{
"name": "By Cost",
"selected": "FALSE"
}
]