This is sort of an follow up to the first post I made, lets say I got two classes:
public class Carinfo {
private String carname;
//The Carinfo[] value is set when making a new car
//so for the object ford the array holds 3 null pointers
private Carinfo [] value;
Carinfo (String someCar, int carValue) {
this.carname = someCar;
this.value = new Carinfo[carValue];
}
}
And the second class:
public class CarPark {
HashMap<String, Carinfo> carGarage;
CarPark() {
carGarage = new HashMap<String, CarInfo>();
Carinfo ford = new Carinfo("Ford", 3);
Carinfo audi = new Carinfo("Audi", 2);
carGarage.put("Ford", ford);
carGarage.put("Audi", audi);
}
}
So let's say for whatever reason I want the object ford who has 3 null pointers
in its Carinfo array, to point at the object audi.
Meaning I can go through the Carinfo objects and list the pointers each car
has to other cars.
Think of it as a family, I want to see what cars are related to each other.
I am having a hard time creating a method that will point to other objects
in my Carinfo HashMap.
Any "pointers"? If anything is unclear please let me rephrase or try to explain it better.
Cheers
I don't really understand what you're trying to do. One way to realize that is to provide a specific method to add a relation. For example, with your array you could do that:
public class CarInfo {
private Carinfo[] value;
public void addCarInfo(CarInfo carInfo, int position) {
value[position] = carInfo;
}
}
Anyway, it is not a good idea to have an array, you should use a List.
I would recommend not storing the relationships between cars inside the Carinfo objects themselves. Instead, you should use a general-purpose graph library (or write your own general-purpose graph library).
As you probably know, a graph is a set of nodes and edges, and each edge represents a relationship between two nodes. The notion that your current code describes is really just a directed graph: each car is a node, and each car can hold some number of references to the other cars, where each reference represents an edge pointing out from that car.
Graphs are such a common abstraction in math and computer science that plenty of libraries have been implemented to represent graphs, with the side benefit that several popular problems are solved for any code that uses the libraries (for instance, finding a multistep relationship between two cars using the fewest number of edges, or finding the smallest number of edges needed in the graph to ensure that all the cars are still indirectly connected). I would recommend searching for already-implemented graph libraries, and then using the one with the best features for your overall problem. If this is a homework assignment, though, you should probably implement your own graph library. This isn't too hard: you need to store nodes and edges somehow (you can just keep a list of nodes, and you could use an edge list or adjacency matrix to store edges), and you will need to provide the algorithms you care about in a somewhat more general form. This may seem like more work, but the benefits of making your code more modular will pay off quickly. You'll create fewer bugs in the first place, since each part of your code performs only one job, and you'll be able to fix bugs more easily and quickly, probably saving you time overall.
For starters you'll need accessing methods on your CarInfo object in order to play with the value array you've set up.
public CarInfo[] getCarValue() {
return value;
}
Now, when you're playing in a method you can call it as follows:
CarInfo[] fordValueArray = carGarage.get("Ford").getCarValue();
This array now points to the one you created on the 3rd command of CarPark().
With that we can do:
fordValueArray[0] = audi;
Now, that all said, it seems a little unclear why you'd set up a class relation like this. The naming of value is seemingly non-intuitive because at face value what you've asked is how we can have a car's value relate to a number of other cars independantly. Ford's first value is an Audi? What are the other two values? Why would we be limited to 3 at all?
Related
I'm a Java newbie with a quick Array vs. ArrayList question. I have an array of objects that can grow or reduce in size, but it's very important for me to maintain the position they were in relative to each other in the array. I'm thinking because of this I need to use Array instead of an ArrayList which can condense/shift elements around if they are removed/added.
The practical example: In my first Java application that I'm slugging through to learn the nuances of this language I'm making a basic poker game simulator. I have Player objects in an array representing the seats they are sitting at, and it's important to know where the dealer button (index) was placed before rotating it. Players being removed or added from an ArrayList will change the indices of the players, and that can throw off the next Player to get it. Dealer button movement is very player-placement specific.
Long story short - is using an Array the best way of handling elements in an array-type structure that need to maintain their position in the array? Is there a better method or logic to accomplish this? I apologize for the simple question but I couldn't find any other alternatives and wanted to confirm that this is the best route to take.
EDIT:
To further clarify, let me give an example of why ArrayList's element movement won't work:
Take three players and their indices in the array:
0 : Player One (Dealer button)
1: Player Two
2: Player Three
If player two (index one) gets up from the table before the dealer button is rotated, depending on the rules player one will keep the button and the blinds will be adjusted accordingly (there's other variants of this rule, but the one I like to use). In an ArrayList, the internal array will be condensed and player three will end up getting the button an extra round before he should. I need to track the empty seat that was active during the hand but was emptied before the round was over and the button moved.
I'm starting to realize that the concept of a "seat" is going to be more complicated, I need to track state on it, including "player just sat down while hand in progress," "player got up while hand in progress," etc. #Stephen P - I think you're right about this, I'm going to need to track them separately and cannot use a simple array structure to determine the logic. Timing of when the elements are added and/or removed is paramount to the application logic, and simply examining if an element is there or not won't cut it.
For the Seats themselves, I'm learning towards ArrayList since the Seats will now always be there, no empties. The Seat will just have a reference to the Player object if one is sitting there as well as WHEN that player arrived. Thanks everyone!
With ArrayList, you can make your players sit tight by using set(int index, T value). You just have to fill the arrayList with nulls first:
List<Player> seats = new ArrayList<>(Collections.nCopies(numPlayers,(Player)null));
seats.set(2,player); // Place a player in the third chair
seats.set(1,null); // Empty the second chair
Long story short - is using an Array the best way of handling elements
in an array-type structure that need to maintain their position in the
array? Is there a better method or logic to accomplish this? I
apologize for the simple question but I couldn't find any other
alternatives and wanted to confirm that this is the best route to
take.
Position shouldn't be your most important criterion for choosing array vs. ArrayList, at least I don't believe it should be.
Arrays are covariant, and more performant most of the time. They mix poorly (if at all) with Java generics which is really kind of a big deal a lot of the time. You cannot create a reference to a new instance of an array of a non-reifiable type (though you can receive one, but buyer beware).
ArrayLists, as a part of the Java Collections API, are invariant. For this reason they work much better with Java generics and, according to Joshua Bloch (Essential Java, 2nd Ed), should be favored much of the time. ArrayLists should often be less performant (and less concise) than arrays. Moreover, as part of the Java Collections API, ArrayLists are more flexible because they extend the List interface which enables you to change implementations from ArrayList to any other List provided that your own class that implements the List is well encapsulated (i.e. the ArrayList is not part of your class's exported API).
There are other differences, of course, but these are the ones that really stand out. If you were really concerned about performance, you could create your own List implementation that was backed by arrays (like ArrayList is) in order to get a feature or the API contract you really wanted. Otherwise, to me, it sounds like you should be using ArrayList (or even other Collection type such as Map (suggested)).
If you have a constant number of seats, you can use either an array or an ArrayAist. If you want to increase the number of seats, you will need an Arraylist, because regular arrays are immutable. See this for more information on the immutability of arrays: Why is an array's length immutable? An ArrayList will never move around its contents if you only use the get(int index) and set(int index, E element)
Also, it is bad practice to let null mean something, even if that something is nothing.
The code:
seat ArrayList initialization
List<Person> seats = new ArrayList<Person>(max_Number_Of_Seats_here);
for(Person person : seats)
{
person = new Person("");
}
//You can then set people like this:
seats.set(seat_index_here, new Person("Darkprozac"));
And have the parameter for the constructor for the class Person be its name.
Person constructor
...
public String name;
public Person(String name)
{
this.name = name;
...
You can then check if the Person's name is "", and if it is, skip that person:
Check if seat is empty
...
for(Person person : seats)
{
if(person.name.equals(""))
{
//do nothing
}
else
{
doSomething();
}
}
...
You can also wrap a Person in a Seat class:
Seat Class
public class Seat
{
public Person person;
public String state;
public Seat(String name)
{
if(name.equals("");
{
state = "empty";
}
else
{
state = "full";
person = new Person(name);
}
}
}
and then modify seat ArrayList initialization and Check if seat is empty accordingly.
Thanks to MrBackend for pointing out that I was wrong about ArrayLists initializing as null.
I would use a map, specifically, a TreeMap.
NavigableMap<Integer, Player> seats = new TreeMap<Integer, Player>();
Integer first = seats.firstKey();
Integer next = seats.nextKey(first);
This gives the benefits of a map, you don't have to worry about seats shifting (even accidentally), and you can still navigate seats easily.
The map manages its own storage (unlike an array) and does not have a risk of shifting indices (unlike an ArrayList).
I currently have 3 arrays of information and am unsure of how to sort them based on one of the values:
int[] rank = { 1, 3, 4, 2, 5 };
String[] game = { "Snake", "Mines", "Fragged", "Siege", "Tower" };
int[] year = { 1980, 1983, 1981, 1995, 1992 };
I'm wanting to sort it by rank, and I've seen many examples of people using comparators to sort 2 parallel arrays, but I haven't seen any example for sorting more than 2.
My first thought was to create a class with a variable for each and then sort that object, but is an extra class really necessary for a sort?
My first thought was to create a class with a variable for each and then sort that object, but is an extra class really necessary for a sort?
It's not strictly necessary - you could definitely write some code to avoid it if you really wanted to. However, I'd say it's a thoroughly good thing.
You don't really have three collections of separate items here: you have one collection of items, each of which has three properties. So make your code match that. Whenever you find you have parallel collections, such that a[0] is related to b[0] is related to c[0] etc, you should think about encapsulating that information in a separate class. It will make your code much easier to maintain, and enforces more consistency.
For example, it would make no sense for those arrays to have different lengths: but there's nothing inherent in the declaration to stop that. If you have one collection, you can't possibly have different numbers of items for the different properties, precisely because you've got one collection.
I think creating a new class would be the cleanest solution. You could manually implement a new sort function to duplicate swaps to the other 2 arrays whenever you apply a swap to the first array (rank), but that gets messy very quickly.
Something like the following would be all you need:
public class Game implements Comparable<Game>{
private int rank = 0;
private int year = 0;
private String name = "";
...
// Constructor +
// Usual getters and setters here
..
public int compareTo(Game anotherGame) {
return this.rank - anotherGame.getRank();
}
}
And then you can simply do:
List<Game> games = new ArrayList<Game>();
...
// Add some games to your games list
...
Collections.sort(games);
Is the extra class necessary? Well no, of course not. You could come up with a sorting routine that would keep everything consistent. However, what happens if next week you decide you need a 4th array, such as a publisher? Now your sorting routine won't work and you have to write a new one.
If you instead write a class to hold these fields as properties, you can simplify the sorting logic immensely, plus you only have to worry about one array. Any extra work you do now will be recouped very quickly then next time you have to maintain this code.
I'm implementing some algorithms to teach myself about graphs and how to work with them. What would you recommend is the best way to do that in Java? I was thinking something like this:
public class Vertex {
private ArrayList<Vertex> outnodes; //Adjacency list. if I wanted to support edge weight, this would be a hash map.
//methods to manipulate outnodes
}
public class Graph {
private ArrayList<Vertex> nodes;
//algorithms on graphs
}
But I basically just made this up. Is there a better way?
Also, I want it to be able to support variations on vanilla graphs like digraphs, weighted edges, multigraphs, etc.
Each node is named uniquely and knows who it is connected to. The List of connections allows for a Node to be connected to an arbitrary number of other nodes.
public class Node {
public String name;
public List<Edge> connections;
}
Each connection is directed, has a start and an end, and is weighted.
public class Edge {
public Node start;
public Node end;
public double weight;
}
A graph is just your collection of nodes. Instead of List<Node> consider Map<String, Node> for fast lookup by name.
public class Graph {
List<Node> nodes;
}
If you need weighted edges and multigraphs, you might want to add another class Edge.
I would also recommend using generics to allow specifying which sub-class of Vertex and Edge are currently used. For example:
public class Graph<V extends Vertex> {
List<V> vertices;
...
}
When it comes to implementing graph algorithms, you could also define interfaces for your graph classes on which the algorithms can operate, so that you can play around with different implementations of the actual graph representation. For example, simple graphs that are well-connected might be better implemented by an adjacency matrix, sparser graphs might be represented by adjacency lists - it all depends...
BTW Building such structures efficiently can be quite challenging, so maybe you could give us some more details on what kind of job you would want to use them for? For more complex tasks I would suggest you have a look at the various Java graph libraries, to get some inspiration.
Take a look at the http://jung.sourceforge.net/doc/index.html graph library. You can still practice implementing your own algorithms (maybe breadth-first or depth-first search to start), but you don't need to worry about creating the graph structure.
Why not keep things simple and use an adjacency matrix or an adjacency list?
Time ago I had the same problem and did my own implementation. What I suggest you is to implement another class: Edge. Then, a Vertex will have a List of Edge.
public class Edge {
private Node a, b;
private directionEnum direction; // AB, BA or both
private int weight;
...
}
It worked for me. But maybe is so simple. There is this library that maybe can help you if you look into its code: http://jgrapht.sourceforge.net/
I'd recommend graphviz highly when you get to the point where you want to render your graphs.
And its companions: take a look at Laszlo Szathmary's GraphViz class, along with notugly.xls.
Even at the time of this question, over 3 years ago, Sage (which is completely free) existed and was pretty good at graph theory. But, in 2012 it is about the best graph theory tool there is. Thus, Sage already has a huge amount of graph theory material built in, including other free and open source stuff that is out there. So, simply messing around with various things to learn more is easy as no programming is required.
And, if you are interested in the programming part as well, first Sage is open source so you can see any code that already exists. And, second, you can re-program any function you want if you really want to practice, or you can be the first to program something that does not already exist. In the latter case, you can even submit that new functionality and make Sage better for all other users.
At this time, this answer may not be that useful to the OP (since it has been 3 years), but hopefully it is useful to any one else who sees this question in the future.
Adjacency List implementation of Graph is appropriate for solving most of the graph related problems.
Java implementation of the same is here on my blog.
class Graph<E> {
private List<Vertex<E>> vertices;
private static class Vertex<E> {
E elem;
List<Vertex<E>> neighbors;
}
}
A simple representation written by 'Robert Sedgwick' and 'Kevin Wayne' is available at http://algs4.cs.princeton.edu/41graph/Graph.java.html
Explanation copied from the above page.
The Graph class represents an undirected graph of vertices
named 0 through V - 1.
It supports the following two primary operations: add an edge to the graph,
iterate over all of the vertices adjacent to a vertex. It also provides
methods for returning the number of vertices V and the number
of edges E. Parallel edges and self-loops are permitted.
By convention, a self-loop v-v appears in the
adjacency list of v twice and contributes two to the degree
of v.
This implementation uses an adjacency-lists representation, which
is a vertex-indexed array of Bag objects.
All operations take constant time (in the worst case) except
iterating over the vertices adjacent to a given vertex, which takes
time proportional to the number of such vertices.
When learning algorithms, the programming language (Java) should not be considered in deciding the representation. Each problem could benefit from a unique representation, and moreover designing it can add a bit of learning. Solve the problem first without relying on a particular language, then the representation for any particular language will flow naturally.
Of course, general representations and libraries are useful in real-world applications. But some of them could benefit from some customization as well. Use the other answers to know the different techniques available, but consider customization when appropriate.
class Vertex {
private String name;
private int score; // for path algos
private boolean visited; // for path algos
List<Edge> connections;
}
class Edge {
private String vertex1Name; // same as Vertex.name
private String vertex2Name;
private int length;
}
class Graph {
private List<Edge> edges;
}
I'm trying to create a structure for a graph. So far I'm trying to make up how I should create some classes for edges.
Edges in graphs can be
Regular,
Directed, Weighted (or any of the above).
So what do you think is the best way to organize this class, I was thinking of creating a interface IEdge, and then create the classes
public interface IEdge{
}
public class DirectedEdge implements IEdge{}
public class WeightedEdge implements IEdge{}
But now I've come with a problem, it's not very flexible, what if I want the following
public class DirectedWeightedEdge implements IEdge{}
How would you code this?
This is no OOP exercise -- I mean, use logic first and then look at the patterns. A directed and an undirected graphs are very different beasts. A directed edge has a start and an end, an undirected one has just two nodes. You may call them start and end in order to get a common base, but there's no such thing as directedness to be added to an edge.
At the same time, edges may have colors, weights, prices, length, capacity, etc. Do you really want to implement ColoredWeightedPricedHavingLenghtCapacityLimitedEdge? Or do you want to use 5 decorators? I hope you don't.
My first point is that the "directedness" doesn't fit nicely in any pattern. You could use an attribute "isDirected" or whatever, and maybe you don't need it at all as most graphs don't mix different kinds of edges. So a single attribute per Graph should do. Quite often, an undirected edge gets represented by a pair of two directed ones.
My second point is that things like weight should in general not be forcibly put in the edge. Using a Map<IEdge, Double> as a property of the Graph does a better job. You can still use objects like Edge and Node, which precludes confusing them (what could easily happen in C where you'd probably use their ids), but keep their properties external.
Why would you explicitly create edges at all? In every graph implementation I've done so far edges existed just implicitly in the node objects. In every node you'll want an array of adjacent nodes - if you need them weighted just add an integer.
Direction follows quite naturally from that as well (well a bidirectional graph is easily represented by a unidirectional..). Obviously you could also save them as an adjacency matrix if the graph is small enough - that's quite nice for parallel algorithms.. but then if performance is important we're talking about sizes where the complete matrix is unuseable.
Edit: After comments I think I should clarify that a bit: Using an Edge class that keeps additional information about the edge (color, weight) is fine, but I'd always use it as part of a specific node: I.e. something like this - in C I'd use a struct for that.
class Node {
List<Edge> children;
class Edge {
int weight;
Color color;
Node dest;
}
}
I'd use a mixture of inheritance and the aforementioned decorator pattern.
Directed and undirected edges behave quite differently, they are mandatory and are mutually exclusive. Therefore they should be the only two implementations of the Edge interface.
Weights, however, are just something you can bolt on an existing edge, so the decorator pattern is the most appropiate for them.
But to return to square one for a moment, depending on how much shared code directed and undirected edges will have, maybe an Edge abstract class would be better than an interface. Of course the "correct" solution is to have both: an interface, implemented by an abstract class, extended by two concrete classes. But in this case this sounds like overengineering.
Use of the decorator pattern may be appropriate here:
http://en.wikipedia.org/wiki/Decorator_pattern
basically, you would have a base class implementing IEdge, and DirectedEdgeDecorator and WeightedEdgeDecorator classes that also implement the IEdge interface. The *Decorator classes would 'wrap' the base edge class and add the additional functionality to it. With this pattern, you can stack multiple decorators on an IEdge, one over the other to modify its behavior in different ways.
You could separate the edge information from the adjacency information. That means you don't duplicate edge data and instead store them in an adjacency list.
public class Node<TEdge> {
class AdjacencyInfo {
Node<TEdge> node;
TEdge edge;
public AdjacencyInfo(Node<TEdge> node, TEdge edge) {
// ....
}
}
bool isDiGraph;
List<AdjacencyInfo> adj;
///.... constructor, other methods
public TEdge ConnectTo(Node<TEdge> node) {
TEdge e = new TEdge();
AdjacencyInfo a0 = new AdjacencyInfo(node, e);
this.adj.Add(a0);
if (!isDiGraph) {
AdjacencyInfo a1 = new AdjacencyInfo(this, e);
node.adj.Add(a1);
}
return e; // return the edge so caller is able to set edge properties (weight, color, etc)
}
}
Something like this should work and clearly solves the directed/non-directed problem. I'm not aware of how much of this can be accomplished using Java generics as they're mostly unusable for other things than avoiding typecasts in containers, but in case you need to be able to handle only weighted edges then you can avoid generics by setting the weight to 1 or whatever makes sense.
one type, with two properties
type Edge
boolean directed = false;
number weight = 1;
I want to implement in Java a class for handling graph data structures. I have a Node class and an Edge class. The Graph class maintains two list: a list of nodes and a list of edges. Each node must have an unique name. How do I guard against a situation like this:
Graph g = new Graph();
Node n1 = new Node("#1");
Node n2 = new Node("#2");
Edge e1 = new Edge("e#1", "#1", "#2");
// Each node is added like a reference
g.addNode(n1);
g.addNode(n2);
g.addEdge(e1);
// This will break the internal integrity of the graph
n1.setName("#3");
g.getNode("#2").setName("#4");
I believe I should clone the nodes and the edges when adding them to the graph and return a NodeEnvelope class that will maintain the graph structural integrity. Is this the right way of doing this or the design is broken from the beginning ?
I work with graph structures in Java a lot, and my advice would be to make any data member of the Node and Edge class that the Graph depends on for maintaining its structure final, with no setters. In fact, if you can, I would make Node and Edge completely immutable, which has many benefits.
So, for example:
public final class Node {
private final String name;
public Node(String name) {
this.name = name;
}
public String getName() { return name; }
// note: no setter for name
}
You would then do your uniqueness check in the Graph object:
public class Graph {
Set<Node> nodes = new HashSet<Node>();
public void addNode(Node n) {
// note: this assumes you've properly overridden
// equals and hashCode in Node to make Nodes with the
// same name .equal() and hash to the same value.
if(nodes.contains(n)) {
throw new IllegalArgumentException("Already in graph: " + node);
}
nodes.add(n);
}
}
If you need to modify a name of a node, remove the old node and add a new one. This might sound like extra work, but it saves a lot of effort keeping everything straight.
Really, though, creating your own Graph structure from the ground up is probably unnecessary -- this issue is only the first of many you are likely to run into if you build your own.
I would recommend finding a good open source Java graph library, and using that instead. Depending on what you are doing, there are a few options out there. I have used JUNG in the past, and would recommend it as a good starting point.
It isn't clear to me why you are adding the additional indirection of the String names for the nodes. Wouldn't it make more sense for your Edge constructor's signature to be something like public Edge(String, Node, Node) instead of public Edge (String, String, String)?
I don't know where clone would help you here.
ETA: If the danger comes from having the node name changed after the node is created, throw an IllegalOperationException if the client tries to call setName() on a node with an existing name.
In my opinion you should never clone the element unless you explicitly state that your data structure does that.
The desired functionality of most things needs the actual object to be passed into the data structure by-reference.
If you want to make the Node class safer, make it an inner class of the graph.
Using NodeEnvelopes or edge/node Factories sounds like overdesign to me.
Do you really want to expose a setName() method on Node at all? There's nothing in your example to suggest that you need that. If you make both your Node and Edge classes immutable, most of the integrity-violation scenarios you're envisioning become impossible. (If you need them to be mutable but only until they're added to a Graph, you could enforce this by having an isInGraph flag on your Node/Edge classes that is set to true by Graph.Add{Node, Edge}, and have your mutators throw an exception if called after this flag is set.)
I agree with jhkiley that passing Node objects to the Edge constructor (instead of Strings) sounds like a good idea.
If you want a more intrusive approach, you could have a pointer from the Node class back to the Graph it resides in, and update the Graph if any critical properties (e.g., the name) of the Node ever change. But I wouldn't do that unless you're sure you need to be able to change the names of existing Nodes while preserving Edge relationships, which seems unlikely.
Object.clone() has some major problems, and its use is discouraged in most cases. Please see Item 11, from "Effective Java" by Joshua Bloch for a complete answer. I believe you can safely use Object.clone() on primitive type arrays, but apart from that you need to be judicious about properly using and overriding clone. You are probably better off defining a copy constructor or a static factory method that explicitly clones the object according to your semantics.
In addition to the comments by #jhkiley.blogspot.com, you can create a factory for Edges and Nodes that refuses to create objects with a name that was already used.