I am trying to create a tournament bracket using linked lists where each match of the tournament is a node that has 2 parent nodes. Is this possible?
Not sure about linked list. I think you need a class Team and a class Match. The match will have 2 fields, Team1 and Team2, a field round (top 16, top8 etc) and a field NextMatch that is an instance of Match, which will be the next round. All these Matches could be placed inside an ArrayList. Or this is how I would do it.
The structure you are describing is a tree, not a list.
While it is theoretically possible to use as list to model an array, and then use the array to model an arbitrary data structure, the result would be a complicated, inefficient mess.
A better idea would be model the matches using a custom Match class; e.g. something like this:
public class Match {
private Player player1;
private Player player2;
private Match leadupMatch1; // null in first round
private Match leadupMatch2; // null in first round
private Match winnersMatch;
private Match losersMatch; // if needed
private Result result;
...
}
public class Player {
...
}
public enum Result {
NONE,
PLAYER_1_WINS,
PLAYER_2_WINS
}
Related
I have data as shown as below. Here if Team 1 is parent & having 2 child Team A & Team B. Team A is again a parent & having player names as child. Team B does not have any child.
Again in another scenario, Team A is independent parent & contains some child etc..
If i give Team 1, then it should fetch records of Team A & Team B as a bundle.
If i give Team A, then it should fetch records of Team A containing its child.
I was thinking to implement this using Map or Tree . and I tried this -
public class Node {
private String id;
private List<Node> children = new ArrayList<>();
private Node parent;
..........
//setters and getters
}
but here creating node dynamically is problem because we don't know the levels of parents(in this example there are 2). means "Dhoni" again contains some child like wise.
How to implements this ?. Please guide.
Whatever i understood from problem description i will try to summarize here.You are looking for a data structure which can take parent name(key) and it might have children, and each child also further can be extended.
public class Node {
private String id; // for each level you have key defined.
private List<Node> children = new ArrayList<>(); //using given key you can get children list
}
You can use map here
Map<String, List<Node>> // here key is team name etc., and list represents children.
If you give team1 as key, you get list which contains teamA, teamB. So if you want to check further, check list size, if it is greater than zero, you can get children(Further you can get all the players defined for both teamA,teamB) otherwise you are at last child.
As per requested by my instructor, we were asked to write a Surgery Room booking program as an assignment. He gave us the following breakdown:
A hospital contains a list (LinkedList) of rooms.
Each room contains a name (I set mine as a room number int) and a list (LinkedList) of bookings.
Each list (LinkedList) of bookings contains a start and end time (I set mines as Date) and a team (another LinkedList).
I've set my GUI and I have an idea of how to construct the methods, I'm just finding it difficult to start since I cannot place two pieces of information in one node (like, putting a name and a list of bookings for a particular room).
If it helps, I have a fully implemented:
LinkedList<T> extends AbstractSequentialList<T> implements List<T>, Deque<T>, Cloneable, Serializable
He gave us most of the code, but although it is mostly complete I'm still a little clueless.
Does anyone have any insight on how to deal with the LinkedList issue? Thanks!
Create a POJO, a class with two fields, and make your LinkedList of that POJO type. For example,
public class Room {
private final int number;
private final List<Bookings> bookings = new LinkedList<>();
public Room(int number) {
this.number = number;
}
public int getNumber() {
return this.number;
}
public List<Bookings> getBookings() {
return bookings;
}
}
And then, you can have a
List<Room> rooms = new LinkedList<>();
Above, creating Bookings with start and end Dates left as an exercise for the reader.
There is a HashMap called flights and an ArrayList called planes. The method is meant to create a new flight if the user enters the name of a plane that exists in this.planes. The only problem is that, with this method, there is no way to create two flights with the same plane and different arrival/departures. When you create a new Flight object with the same plane as a previous one, it REPLACES that previous one. I'm wondering how I can keep that from happening.
public void addFlight(String planeID, String departure, String arrival) {
Flight newFlight = null;
for(Plane p : this.planes) {
if(p.getID().equals(planeID)) {
newFlight = new Flight(p, departure, arrival);
}
}
flights.put(planeID, newFlight);
}
Since the planeID String being entered determines the plane from this.planes that is assigned to the new Flight, I made a loop that runs through the planes ArrayList to check if the name matches. I'm pretty sure this is what's keeping me from being able to make multiple "Flights" that have the same "Plane" but I don't know what else I can change. I tried adding in this additional if statement but it didn't do what I thought it would.
else if (this.flights.keySet().contains(p.getID())) {
newFlight = new Flight(p, departure, arrival); //In case it is a repeated Plane
}
You need this
HashMap<String,List<Flight>>
instead of
HashMap<String,Flight>
This will help you maintain more than one Flight instances in the list mapped with the planeID
Flights is a HashMap. This is a data structure that stores items in key/value pairs. In your case, planeID is the key. So when you are inserting a new flight, it will check the map's contents, see the existing Plane ID & insert your new flight in it's place. It's how the data structure works.
You need to use something more unique as the key. An object combining the plane ID & some departure details perhaps?
Create HashMap for planes and ArrayList of flights in stead.
Your design will much more be simplified and you'll get the expected behavior.
Adding code would become
public void addFlight(String planeID, String departure, String arrival) {
flights.add(planes.get(planeID), departure, arrival);
}
No need to search, check or worry.
Good luck.
Edit in response to the comment:
You are using plane id's as keys to the HashMap. So whichever is unique w.r.t. the key, should be placed in the HashMap. Which in this case is plane.
For storing flights, there were two choices
Aggregation: HashMap<Plane, List<Flight>> as suggested by Octopus
Association: List<Flight> with Plane as a member of Flight class.
Both choices are easy to use, but in first choice, your plane reference inside flight class is redundant. So I'd go for second choice.
You should choose whichever suits you best.
Hope this helps.
My graph contains nodes called points and lines.
There is a relationship type called "NEXT", which connects two points and has a property called lineID (a long). A line node consists simply of an ID and a reference to a "root" point. To traverse a line is to start with its root node and follow the NEXT relationships whose lineID matches the id of the line being traversed. To clarify, if we're traversing a line with ID 123, whose root point has id 321, the Cypher traversal would be:
START n = node(321)
MATCH (n)-[rel:NEXT*{lineID:123}]->(x)
RETURN collect(rel)
A line, then, is essentially a linked list of Next relationships with matching lineID properties. That said, I don't want to persist this list as a property of lines - I want the list to be constructed by a traversal when a line is loaded.
What are my options for implementing this in spring-data-neo4j? Specifically, should "lines" exist as NodeEntitys, and if so what should they contain?
#NodeEntity
class Line {
#RelatedTo(type="ROOT")
Point root;
#RelatedToVia(type="NEXT")
Iterable<Item> list;
doesn't quite fit, because the line is not related via Next relationships to the item, the root point is. It also fails to address the fact that those NEXT relationships need to have a lineID property matching the line's ID (which becomes important because some points exist on multiple lines - i.e. they have multiple NEXT relationships with different lineID's). I have a hunch that the solution will involve annotating the list as a #GraphTraversal, but I don't understand how that would work.
I'm doing this largely as an exercise to wrap my head around data modeling in SDN, in the context of wrapping my head around Neo4j and graph databases in general. If the question I'm asking reveals a flaw in my understanding of any of these things, I'd be very appreciative if someone could point it out.
This should be a suitable model for your entities:
#NodeEntity
class Point {
#GraphId
protected Long id;
#RelatedToVia(type="NEXT")
Set<Edge> edges;
}
#NodeEntity
class Line {
#GraphId
protected Long id;
#RelatedTo(type="ROOT")
Point root;
}
#RelationshipEntity
public class Edge {
#GraphId
protected Long id;
#StartNode private Point from;
#EndNode private Point to;
#RelatedTo(type="LINE")
Line line;
}
It easily allows both programmatic navigation in Java as in:
Set edges = line.getPoint().getEdges();
for (Edge edge: edges) {
if (edge.getLine().getId() == id) {
...
}
}
or Cypher queries like the one you listed.
I am teaching myself Java and I have a simple package with three classes - shop, product and shelf. A shop object contains many shelves, and a shelf contains many products, and, in this case, each product is only available on one shelf.
A product looks like this:
public class t_product {
private t_shelf shelf;
private String name;
}
And a shelf looks like this:
public class t_shelf {
private Set<t_product> products = new HashSet<>();
private String name;
}
The shop object looks like this:
public class t_shop {
private Set<t_shelf> shelves = new HashSet<>();
}
I also have a set of functions which will add or remove a product from the shelf.
myshelf.addProduct(myproduct);
will set myproduct.shelf = myshelf, and add myproduct to myshelf.products. This works fine, and handles the relationship nicely. Similar functions link shop and shelves.
Moving on to the problem
I have a .csv which stores:
Product | Shelf
----------------------
Hats | Headwear
Helmets | Headwear
Socks | Footwear
Apples | Fruit
Bananas | Fruit
Oranges | Fruit
When parsing the .csv, I want to search for the shelf by name to see if it has already been created, so, for example, on reading a line "Bananas, Fruit", it would process:
if (!myshop.getShelfByName("Fruit")){
myshop.addShelf(new t_shelf("Fruit"));
}
myshop.getShelfByName("Fruit").addProduct("Bananas"); //Constructors accept the name as a parameter.
My question is:
Is there a neater implementation of getShelfByName(String name) than simply iterating through the HashSet and checking for the name against every single item? (Want to avoid O(N) algorithms).
Thanks!
Any attempt to solve this VERY gratefully received :)
If you're creating classes of objects to be held in a HashSet, you must give these classes decent equals() and hashCode() override methods, ones that make sense and that play well together (that for one use the same invariant fields to determine their results).
As for your specific question, consider putting things in HashMaps rather than HashSets, as then you can easily find the object by its key.
You should store your shelves in a HashMap (the key should be the name of the shelve).
You will have a O(1) algorithm.
public class t_shop {
private Map<String, t_shelf> shelves = new HashMap<String, t_shelf>();
public void addShelve(t_shelf) {
shelves.put(t_shelf.getName(), t_shelf);
}
public tshelf getShelfByName(String name) {
return shelves.get(name);
}
}
t_shelf shelf = myshop.getShelfByName("Fruit");
if (null != shelf){
shelf = new t_shelf("Fruit");
myshop.addShelf(shelf);
}
shelf.addProduct("Bananas");
Using a HashMap instead of a Set would make looking for a named shelf trivial:
private Map<String, t_shelf> shelves = new HashMap<>();
// ...
if (shelves.contains(name)) {
t_shelf shelf = shelves.get(name);
shelf.addProduct(product);