Implementing TreeModel - java

I am trying to write a class that implements the TreeModel class. I was hoping someone could guide me in the right direction. Below is my class. The problem is when I bind it to a jTree Component, the second level keeps being added over and over. So I suspect my reference to the parent object is wrong:
public class PMEntry implements TreeModel{
private String title;
private List<PMEntry> pmEntryCollection;
private String pmId;
private String href;
private PMEntry root;
private ModuleType type;
public PMEntry (PMEntry root){
this.root = root;
}
#Override
public Object getRoot() {
return ((PMEntry)this.root);
}
#Override
public Object getChild(Object o, int i) {
if(getPmEntryCollection().isEmpty()){
return null;
}else {
return (PMEntry) getPmEntryCollection().get(i);
}
}
#Override
public int getChildCount(Object o) {
if(getPmEntryCollection().isEmpty()){
return 0;
}else {
return getPmEntryCollection().size();
}
}
#Override
public boolean isLeaf(Object o) {
PMEntry pmentry = (PMEntry)o;
return (pmentry.getType() == ModuleType.DM) ? true : false;
}
#Override
public void valueForPathChanged(TreePath tp, Object o) {
//todo
}
#Override
public int getIndexOfChild(Object parent, Object child) {
if (!(parent instanceof PMEntry)){
System.out.println("Returning -1");
return -1;
}
PMEntry pParent = (PMEntry) parent;
List<PMEntry> children = pParent.getPmEntryCollection();
if (children == null) {
System.out.println("children = null, Returning -1");
return -1;
}
for (int i = 0; i < children.size(); i++) {
System.out.println("Child:" + child);
if (children.get(i) == child) {
return i;
}
}
return -1;
}
#Override
public void addTreeModelListener(TreeModelListener tl) {
//todo
}
#Override
public void removeTreeModelListener(TreeModelListener tl) {
//todo
}
#Override
public String toString(){
return this.getTitle();
}
public enum ModuleType {
PM,
DM
}
// getters and setters here....
And here is a snippet of how I am binding the data
PMEntry tm = new PMEntry(null);
tm.setTitle("Root");
PMEntry pmRoot = new PMEntry((PMEntry)(tm));
pmRoot.setTitle("Project");
PMEntry pm1 = new PMEntry(pmRoot);
pm1.setType(PMEntry.ModuleType.DM);
pm1.setTitle("Publication Module");
PMEntry pm2 = new PMEntry(pmRoot);
pm2.setType(PMEntry.ModuleType.PM);
pm2.setTitle("Chapter");
List<PMEntry> pmCollection = new ArrayList<PMEntry>();
List<PMEntry> pmCollection1 = new ArrayList<PMEntry>();
PMEntry pm3 = new PMEntry(null);
pm3.setType(PMEntry.ModuleType.DM);
pm3.setTitle("Data Module");
PMEntry pm4 = new PMEntry(null);
pm4.setType(PMEntry.ModuleType.DM);
pm4.setTitle("Data Module");
pmCollection1.add(pm3);
pmCollection1.add(pm4);
pm2.setPmEntryCollection(pmCollection1);
pmCollection.add(pm1);
pmCollection.add(pm2);
pmRoot.setPmEntryCollection(pmCollection);
this.jTree1.setModel(pmRoot);

I'd wonder why you think you need to implement TreeModel. Have you looked into DefaultTreeModel? What new behavior over and above that class do you plan to implement?

I have to agree with #duffymo & #HFOE: don't reject DefaultTreeModel prematurely. There's an example here that illustrates a TreeCellEditor for editing the name of a userObject.
If you really do need to implement TreeModel, FileTreeModel, discussed here, is a fairly accessible example.

Related

raw type error occuring where no raw types are used

Here is a link-based Stack class.
import java.util.Iterator;
public class LStack<T>
{
private Link top;
private int size;
public LStack()
{
top = null;
size = 0;
}
#Override
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append("[");
for(Link nav = top; nav != null; nav=nav.getNext())
{
sb.append(nav.getDatum());
if(nav.getNext() != null)
{
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
public void push(T newItem)
{
top = new Link(newItem, top);
size++;
}
public T pop()
{
if(isEmpty())
{
throw new EmptyStackException();
}
size--;
T out = top.getDatum();
top = top.getNext();
return out;
}
public T peek()
{
if(isEmpty())
{
throw new EmptyStackException();
}
return top.getDatum();
}
public void clear()
{
top = null;
size = 0;
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return top == null;
}
public Iterator<T> iterator()
{
return new LStackIterator();
}
/********************aliens*******************/
class LStackIterator implements Iterator<T>
{
private Link current;
public LStackIterator()
{
current = top;
}
public T next()
{
T out = current.getDatum();
current = current.getNext();
return out;
}
public boolean hasNext()
{
return current.getNext() != null;
}
}
public static void main(String[] args)
{
LStack<String> elStack = new LStack<>();
elStack.push("A");
elStack.push("B");
elStack.push("C");
elStack.push("D");
for(String quack: elStack)
{
System.out.println(quack);
}
System.out.printf("The size is %d\n", elStack.size());
System.out.println(elStack);
System.out.println(elStack.pop());
System.out.println(elStack.pop());
System.out.println(elStack.pop());
System.out.println(elStack.pop());
System.out.println(elStack);
}
class Link
{
private T datum;
private Link next;
public Link(T datum, Link next)
{
this.datum = datum;
this.next = next;
}
public Link(T datum)
{
this(datum, null);
}
public T getDatum()
{
return datum;
}
public Link getNext()
{
return next;
}
}
}
I then try to run and get this.
$ javac LStack.java
LStack.java:95: error: incompatible types: Object cannot be converted to String
for(String quack: elStack)
^
1 error
What is happening here? Changing the type from String to Object causes it to work, but I am not using any raw types.
You must implement Iterable for "For-Each" loop
public class LStack<T> implements Iterable<T>

Implementing an Iterator on Composite Design Pattern Through Separate Class - Is It programmatically valid?

I have implemented the Composite Design Pattern and then expanded the Composite class to also implement Iterable, however the iterator() method (which returns an iterator object) is also part of the abstract Component class and is then implemented by the Composite class (but not the Leaf class).
I want to implement a depth first and breadth first search for a tree-like structure. See summarized code below:
public abstract class Component {
public void add() {
}
public void remove() {
}
public ArrayList<Component> getItems() {
}
public ItemIterator iterator() {
}
public class Composite extends Component implements Iterable<Component> {
ArrayList<Component> items = new ArrayList<Component>();
String name;
public ItemIterator iterator() {
return new ItemIterator(this);
}
public Composite(String name) {
this.name = name;
}
public getName() {
// returns name
}
public ArrayList<Component> getItems() {
return this.items;
}
public class ItemIterator implements Iterator<Component> {
ArrayList<Component> breadthFirstSearch = new ArrayList<Component>();
Component currentItem;
public ItemIterator(Component firstItem) {
currentItem = firstItem;
breadthFirstSearch.add(currentItem);
}
public boolean hasNext() {
if (breadthFirstSearch.isEmpty()) {
return false;
}
return true;
}
public Component next() {
// This method pops the root item the first time, creates its children,
// places at end of ArrayList,
// then returns the root. Second time the same operations are performed
// on the following item in the breadth first traversal of the tree.
if (hasNext()) {
Component nextItem = breadthFirstSearch.get(0);
if (nextItem instanceof Composite) {
for (Component item : currentItem.getItems()) {
breadthFirstSearch.add(item);
}
}
breadthFirstSearch.remove(0);
if (hasNext()) {
currentItem = breadthFirstSearch.get(0);
}
return nextItem;
}
return null;
}
public class Demo {
public static void main(String[] args) {
Component bag = new Composite("bag");
Component plasticBag = new Composite("plastic bag");
Component makeupBag = new Composite("makeup bag");
Component phone = new Composite("phone");
Component lipstick = new Composite("lipstick");
Component mascara = new Composite("mascara");
bag.add(plasticBag); bag.add(makeupBag);
plasticbag.add(phone); makeupBag.add(lipstick); makeupBag.add(mascara);
ItemIterator itr = bag.iterator();
while (itr.hasNext()) {
System.out.println(itr.next().getName());
}
}
}
The code above compiles and runs fine, it works. However, I am not certain of whether it is programmatically acceptable. The structure of it seems to fundamentally go against other Iterator implementations that I have seen (implementations that I discovered after finishing the above solution), but I can't quite grasp/explain what is so wrong about it. The other way of implementing Iterable (in a different context) was of the form:
public abstract class Component {
public void add() {
}
public void remove() {
}
public ArrayList<Component> getItems() {
}
}
Note the lack of an iterator() method in the abstract class above.
public class Composite extends Component implements Iterable<Component> {
ArrayList<Component> items = new ArrayList<Component>();
String name;
public Iterator<Component> iterator() {
return new Iterator() {
public boolean hasNext() {
// Code
}
public Iterator<Component> next() {
// Code
};
}
public Composite(String name) {
this.name = name;
}
public getName() {
// returns name
}
public ArrayList<Component> getItems() {
return this.items;
}
}
Which way of structuring the solution is better, and is my way of doing it outright wrong/bad practice and if so, why? I am new to Java, so I apologize if this turns out to be a bad question.
I think you described the visitor pattern:
interface Visitable {
void accept(Visitor v);
}
class Visitor {
void visit(Component c){
c.doFooBar();// implement your logic here
}
}
class Component implements Visitable {
private List<Component> children;
void accept(Visitor v){
v.visit(this);
children.forEach(child -> child.accept(v)); // sumbit the visitor/iterator down the composite tree
}
}
public static void main(String[] args){
Component composite = Factory.createComposite();
composite.accept(new Visitor());
}
Instead of having iterator build up a list of pending items to iterate, it should just store a list of pending iterators to traverse.
Here is a Minimal, Reproducible Example:
public final class Node {
private final String name;
private List<Node> children = new ArrayList<>();
public Node(String name) {
this.name = name;
}
public Node(String name, Node... children) {
this.name = name;
this.children.addAll(Arrays.asList(children));
}
public String getName() {
return this.name;
}
public List<Node> getChildren() {
return this.children;
}
public Iterable<Node> breadthFirstSearch() {
return () -> new NodeIterator(this, true);
}
public Iterable<Node> depthFirstSearch() {
return () -> new NodeIterator(this, false);
}
#Override
public String toString() {
return "Node[" + this.name + "]";
}
}
public final class NodeIterator implements Iterator<Node> {
private final Deque<Iterator<Node>> iterators = new ArrayDeque<>();
private final boolean breadthFirst;
public NodeIterator(Node node, boolean breadthFirst) {
this.iterators.add(Collections.singleton(node).iterator());
this.breadthFirst = breadthFirst;
}
#Override
public boolean hasNext() {
return ! this.iterators.isEmpty();
}
#Override
public Node next() {
Iterator<Node> iterator = this.iterators.removeFirst();
Node node = iterator.next();
if (iterator.hasNext())
this.iterators.addFirst(iterator);
if (! node.getChildren().isEmpty()) {
if (this.breadthFirst)
this.iterators.addLast(node.getChildren().iterator());
else
this.iterators.addFirst(node.getChildren().iterator());
}
return node;
}
}
Test
Node root = new Node("root",
new Node("1",
new Node("1.1",
new Node("1.1.1"),
new Node("1.1.2")),
new Node("1.2",
new Node("1.2.1"),
new Node("1.2.2"))
),
new Node("2",
new Node("2.1",
new Node("2.1.1"),
new Node("2.1.2")),
new Node("2.2",
new Node("2.2.1"),
new Node("2.2.2"))));
for (Node node : root.breadthFirstSearch())
System.out.println(node);
System.out.println();
for (Node node : root.depthFirstSearch())
System.out.println(node);
Output
Node[root]
Node[1]
Node[2]
Node[1.1]
Node[1.2]
Node[2.1]
Node[2.2]
Node[1.1.1]
Node[1.1.2]
Node[1.2.1]
Node[1.2.2]
Node[2.1.1]
Node[2.1.2]
Node[2.2.1]
Node[2.2.2]
Node[root]
Node[1]
Node[1.1]
Node[1.1.1]
Node[1.1.2]
Node[1.2]
Node[1.2.1]
Node[1.2.2]
Node[2]
Node[2.1]
Node[2.1.1]
Node[2.1.2]
Node[2.2]
Node[2.2.1]
Node[2.2.2]

ANTLR4 parse tree to DOT using DOTGenerator

How do I use DOTGenerator to convert a parse tree to DOT/graphviz format in ANTLR4?
I found this related question but the only answer uses TreeViewer to display the tree in a JPanel and that's not what I'm after. This other question is exacly what I need but it didn't get answered. Everything else I stumbled upon relates to DOTTreeGenerator from ANTLR3 and it's not helpful.
I'm using Java with the ANTLR4 plugin for IntelliJ.
I have a small project that has all kind of utility methods w.r.t. ANTLR4 grammar debugging/testing. I haven't found the time to provide it of some proper documentation so that I can put it on Github. But here's a part of it responsible for creating a DOT file from a grammar.
Stick it all in a single file called Main.java (and of course generate the lexer and parser for Expression.g4), and you will see a DOT string being printed to your console:
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
import java.util.*;
public class Main {
public static void main(String[] args) {
/*
// Expression.g4
grammar Expression;
expression
: '-' expression
| expression ('*' | '/') expression
| expression ('+' | '-') expression
| '(' expression ')'
| NUMBER
| VARIABLE
;
NUMBER
: [0-9]+ ( '.' [0-9]+ )?
;
VARIABLE
: [a-zA-Z] [a-zA-Z0-9]+
;
SPACE
: [ \t\r\n] -> skip
;
*/
String source = "3 + 42 * (PI - 3.14159)";
ExpressionLexer lexer = new ExpressionLexer(CharStreams.fromString(source));
ExpressionParser parser = new ExpressionParser(new CommonTokenStream(lexer));
SimpleTree tree = new SimpleTree.Builder()
.withParser(parser)
.withParseTree(parser.expression())
.withDisplaySymbolicName(false)
.build();
DotOptions options = new DotOptions.Builder()
.withParameters(" labelloc=\"t\";\n label=\"Expression Tree\";\n\n")
.withLexerRuleShape("circle")
.build();
System.out.println(new DotTreeRepresentation().display(tree, options));
}
}
class DotTreeRepresentation {
public String display(SimpleTree tree) {
return display(tree, DotOptions.DEFAULT);
}
public String display(SimpleTree tree, DotOptions options) {
return display(new InOrderTraversal().traverse(tree), options);
}
public String display(List<SimpleTree.Node> nodes, DotOptions options) {
StringBuilder builder = new StringBuilder("graph tree {\n\n");
Map<SimpleTree.Node, String> nodeNameMap = new HashMap<>();
int nodeCount = 0;
if (options.parameters != null) {
builder.append(options.parameters);
}
for (SimpleTree.Node node : nodes) {
nodeCount++;
String nodeName = String.format("node_%s", nodeCount);
nodeNameMap.put(node, nodeName);
builder.append(String.format(" %s [label=\"%s\", shape=%s];\n",
nodeName,
node.getLabel().replace("\"", "\\\""),
node.isTokenNode() ? options.lexerRuleShape : options.parserRuleShape));
}
builder.append("\n");
for (SimpleTree.Node node : nodes) {
String name = nodeNameMap.get(node);
for (SimpleTree.Node child : node.getChildren()) {
String childName = nodeNameMap.get(child);
builder.append(" ").append(name).append(" -- ").append(childName).append("\n");
}
}
return builder.append("}\n").toString();
}
}
class InOrderTraversal {
public List<SimpleTree.Node> traverse(SimpleTree tree) {
if (tree == null)
throw new IllegalArgumentException("tree == null");
List<SimpleTree.Node> nodes = new ArrayList<>();
traverse(tree.root, nodes);
return nodes;
}
private void traverse(SimpleTree.Node node, List<SimpleTree.Node> nodes) {
if (node.hasChildren()) {
traverse(node.getChildren().get(0), nodes);
}
nodes.add(node);
for (int i = 1; i < node.getChildCount(); i++) {
traverse(node.getChild(i), nodes);
}
}
}
class DotOptions {
public static final DotOptions DEFAULT = new DotOptions.Builder().build();
public static final String DEFAULT_PARAMETERS = null;
public static final String DEFAULT_LEXER_RULE_SHAPE = "box";
public static final String DEFAULT_PARSER_RULE_SHAPE = "ellipse";
public static class Builder {
private String parameters = DEFAULT_PARAMETERS;
private String lexerRuleShape = DEFAULT_LEXER_RULE_SHAPE;
private String parserRuleShape = DEFAULT_PARSER_RULE_SHAPE;
public DotOptions.Builder withParameters(String parameters) {
this.parameters = parameters;
return this;
}
public DotOptions.Builder withLexerRuleShape(String lexerRuleShape) {
this.lexerRuleShape = lexerRuleShape;
return this;
}
public DotOptions.Builder withParserRuleShape(String parserRuleShape) {
this.parserRuleShape = parserRuleShape;
return this;
}
public DotOptions build() {
if (lexerRuleShape == null)
throw new IllegalStateException("lexerRuleShape == null");
if (parserRuleShape == null)
throw new IllegalStateException("parserRuleShape == null");
return new DotOptions(parameters, lexerRuleShape, parserRuleShape);
}
}
public final String parameters;
public final String lexerRuleShape;
public final String parserRuleShape;
private DotOptions(String parameters, String lexerRuleShape, String parserRuleShape) {
this.parameters = parameters;
this.lexerRuleShape = lexerRuleShape;
this.parserRuleShape = parserRuleShape;
}
}
class SimpleTree {
public static class Builder {
private Parser parser = null;
private ParseTree parseTree = null;
private Set<Integer> ignoredTokenTypes = new HashSet<>();
private boolean displaySymbolicName = true;
public SimpleTree build() {
if (parser == null) {
throw new IllegalStateException("parser == null");
}
if (parseTree == null) {
throw new IllegalStateException("parseTree == null");
}
return new SimpleTree(parser, parseTree, ignoredTokenTypes, displaySymbolicName);
}
public SimpleTree.Builder withParser(Parser parser) {
this.parser = parser;
return this;
}
public SimpleTree.Builder withParseTree(ParseTree parseTree) {
this.parseTree = parseTree;
return this;
}
public SimpleTree.Builder withIgnoredTokenTypes(Integer... ignoredTokenTypes) {
this.ignoredTokenTypes = new HashSet<>(Arrays.asList(ignoredTokenTypes));
return this;
}
public SimpleTree.Builder withDisplaySymbolicName(boolean displaySymbolicName) {
this.displaySymbolicName = displaySymbolicName;
return this;
}
}
public final SimpleTree.Node root;
private SimpleTree(Parser parser, ParseTree parseTree, Set<Integer> ignoredTokenTypes, boolean displaySymbolicName) {
this.root = new SimpleTree.Node(parser, parseTree, ignoredTokenTypes, displaySymbolicName);
}
public SimpleTree(SimpleTree.Node root) {
if (root == null)
throw new IllegalArgumentException("root == null");
this.root = root;
}
public SimpleTree copy() {
return new SimpleTree(root.copy());
}
public String toLispTree() {
StringBuilder builder = new StringBuilder();
toLispTree(this.root, builder);
return builder.toString().trim();
}
private void toLispTree(SimpleTree.Node node, StringBuilder builder) {
if (node.isLeaf()) {
builder.append(node.getLabel()).append(" ");
}
else {
builder.append("(").append(node.label).append(" ");
for (SimpleTree.Node child : node.children) {
toLispTree(child, builder);
}
builder.append(") ");
}
}
#Override
public String toString() {
return String.format("%s", this.root);
}
public static class Node {
protected String label;
protected int level;
protected boolean isTokenNode;
protected List<SimpleTree.Node> children;
Node(Parser parser, ParseTree parseTree, Set<Integer> ignoredTokenTypes, boolean displaySymbolicName) {
this(parser.getRuleNames()[((RuleContext)parseTree).getRuleIndex()], 0, false);
traverse(parseTree, this, parser, ignoredTokenTypes, displaySymbolicName);
}
public Node(String label, int level, boolean isTokenNode) {
this.label = label;
this.level = level;
this.isTokenNode = isTokenNode;
this.children = new ArrayList<>();
}
public void replaceWith(SimpleTree.Node node) {
this.label = node.label;
this.level = node.level;
this.isTokenNode = node.isTokenNode;
this.children.remove(node);
this.children.addAll(node.children);
}
public SimpleTree.Node copy() {
SimpleTree.Node copy = new SimpleTree.Node(this.label, this.level, this.isTokenNode);
for (SimpleTree.Node child : this.children) {
copy.children.add(child.copy());
}
return copy;
}
public void normalizeLevels(int level) {
this.level = level;
for (SimpleTree.Node child : children) {
child.normalizeLevels(level + 1);
}
}
public boolean hasChildren() {
return !children.isEmpty();
}
public boolean isLeaf() {
return !hasChildren();
}
public int getChildCount() {
return children.size();
}
public SimpleTree.Node getChild(int index) {
return children.get(index);
}
public int getLevel() {
return level;
}
public String getLabel() {
return label;
}
public boolean isTokenNode() {
return isTokenNode;
}
public List<SimpleTree.Node> getChildren() {
return new ArrayList<>(children);
}
private void traverse(ParseTree parseTree, SimpleTree.Node parent, Parser parser, Set<Integer> ignoredTokenTypes, boolean displaySymbolicName) {
List<SimpleTree.ParseTreeParent> todo = new ArrayList<>();
for (int i = 0; i < parseTree.getChildCount(); i++) {
ParseTree child = parseTree.getChild(i);
if (child.getPayload() instanceof CommonToken) {
CommonToken token = (CommonToken) child.getPayload();
if (!ignoredTokenTypes.contains(token.getType())) {
String tempText = displaySymbolicName ?
String.format("%s: '%s'",
parser.getVocabulary().getSymbolicName(token.getType()),
token.getText()
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t")
.replace("'", "\\'")) :
String.format("%s",
token.getText()
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t"));
if (parent.label == null) {
parent.label = tempText;
}
else {
parent.children.add(new SimpleTree.Node(tempText, parent.level + 1, true));
}
}
}
else {
SimpleTree.Node node = new SimpleTree.Node(parser.getRuleNames()[((RuleContext)child).getRuleIndex()], parent.level + 1, false);
parent.children.add(node);
todo.add(new SimpleTree.ParseTreeParent(child, node));
}
}
for (SimpleTree.ParseTreeParent wrapper : todo) {
traverse(wrapper.parseTree, wrapper.parent, parser, ignoredTokenTypes, displaySymbolicName);
}
}
#Override
public String toString() {
return String.format("{label=%s, level=%s, isTokenNode=%s, children=%s}", label, level, isTokenNode, children);
}
}
private static class ParseTreeParent {
final ParseTree parseTree;
final SimpleTree.Node parent;
private ParseTreeParent(ParseTree parseTree, SimpleTree.Node parent) {
this.parseTree = parseTree;
this.parent = parent;
}
}
}
And if you paste the output in a DOT viewer, you will get this:
You may also want to look at alternatives. DOT graphs aren't the pretties among possible graph representations. Maybe you like an svg graph instead? If so have a look at the ANTLR4 grammar extension for Visual Studio Code, which generates and exports an svg graphic with the click of a mouse button (and you can style that with own CSS code).

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.

instantiate the recursively defined composite generic classes in java

I defined classes Graph containing GraphNode as follows, my intention for declaring N is to compare 2 GraphNode objects using generics.
The question is how shall I instantiate the Graph which is recursively bound.
error while declaring as below.
Graph<Integer,Comparable<GraphNode>> graph = new Graph<>();
Bound mismatch: The type Comparable<GraphNode> is not a valid substitute for the bounded parameter <N extends Comparable<GraphNode<T,N>>> of the type Graph<T,N>
public class Graph<T, N extends Comparable<GraphNode<T, N>>> {
private N root;
private Class<N> clazz;
Graph(Class<N> clazz) {
this.clazz = clazz;
}
public N getInstance() {
try {
return clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
#SuppressWarnings("unchecked")
public void insert(T d, N n) {
if (root == null && n == null)
root = getInstance();
if (root == null)
root = n;
N node = root;
while (node != null) {
if (node.equals(n)) {
N newNode = getInstance();
((GraphNode<T, N>) newNode).setAdjNode(newNode);
}
}
}
}
public class GraphNode<T, N extends Comparable<GraphNode<T, N>>> implements Comparable<N> {
private T data;
private LinkedHashSet<N> adjNodes = new LinkedHashSet<>();
GraphNode() {
data = null;
}
GraphNode(T d) {
setData(d);
}
public void setAdjNode(N n) {
adjNodes.add(n);
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
#Override
public int hashCode() {
return data.hashCode();
}
#Override
public boolean equals(Object obj) {
if (obj instanceof GraphNode<?, ?>) {
return ((GraphNode<?, ?>) obj).getData() == this.getData();
}
return false;
}
#Override
public String toString() {
return data + "";
}
#Override
public int compareTo(N o) {
return this.compareTo(o);
}
}
This solved my above problem
public class Graph<T extends Comparable<T>> {
private GraphNode<T> root;
public void insert(T d, GraphNode<T> n) {
if (root == null && n == null)
root = new GraphNode<T>(d);
if (root == null)
root = n;
GraphNode<T> node = root;
Queue<GraphNode<T>> queue = new ConcurrentLinkedQueue<>();
queue.add(root);
while (!queue.isEmpty()) {
node = queue.poll();
node.setNodeColor(color.BLACK);
if (node.equals(n)) {
GraphNode<T> newNode = new GraphNode<T>(d);
((GraphNode<T>) newNode).setAdjNode(newNode);
} else {
queue.addAll(node.getUnexploredAdjNodes());
}
}
}
}
public class GraphNode<T extends Comparable<T>> implements Comparable<GraphNode<T>> {
enum color {
WHITE, GREY, BLACK
};
private T data;
private color nodeColor = color.WHITE;
private LinkedHashSet<GraphNode<T>> adjNodes = new LinkedHashSet<>();
GraphNode() {
data = null;
}
GraphNode(T d) {
setData(d);
}
public void setAdjNode(GraphNode<T> n) {
adjNodes.add(n);
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public LinkedHashSet<GraphNode<T>> getAdjNodes() {
return adjNodes;
}
public LinkedHashSet<GraphNode<T>> getUnexploredAdjNodes() {
LinkedHashSet<GraphNode<T>> n = new LinkedHashSet<>();
for (GraphNode<T> node : adjNodes) {
if (node.getNodeColor() == color.WHITE)
n.add(node);
}
return n;
}
public color getNodeColor() {
return nodeColor;
}
public void setNodeColor(color nodeColor) {
this.nodeColor = nodeColor;
}
#Override
public int hashCode() {
return data.hashCode();
}
#Override
public boolean equals(Object obj) {
if (obj instanceof GraphNode<?>) {
return ((GraphNode<?>) obj).getData() == this.getData();
}
return false;
}
#Override
public int compareTo(GraphNode<T> o) {
return data.compareTo(o.data);
}
#Override
public String toString() {
return data + "";
}
}
Graph<Integer> graph = new Graph<>();

Categories

Resources