toString() for a List Stack - java

i have a class for List, Node, and Stack.
The classes List, Node are all done, now i want to finish my Stack.class, which uses my List.class.
Now i am in my main method and i want to try out my push/pop methods, but don't know how to output them as strings.
I did this in my List.class, but don't know how to recreate it for the Stack.class.
Can someone help me? Thanks.
public class Stack {
private List list;
public Stack() {
list = new List();
}
public class List{
public String toString() {
Node temp = head;
String string = "";
while (temp != null && temp.getNext() != null) {
string = string + temp.getElement() + ", ";
temp = temp.getNext();
}
if (temp != null) {
string = string + temp.getElement() + ".";
}
return string;
}

In your Stack class, you could invoke list.toString(). Something like
public String toString() {
return String.format("Stack: %s", list.toString());
}

you have to "concatenate" the 2 toString() method.
So you have to create a new toString() in your Stack class.
public class Stack {
private List list;
public Stack() {
list = new List();
}
public String toString()
{
String myreturn = "//Anything you need" + list.toString();
return myreturn;
}}

You can handle each element in the list:
For example, if you need get list values by comma separate:
public String toString() {
return list.stream()
.map(Objects::toString)
.collect(Collectors.joining(","));
}
Or you need also modify each value:
public String toString() {
return list.stream()
.map(p -> "[" + p.toString() + "]")
.collect(Collectors.joining(","));
}

Related

"Recursive" listToString()-method in linked lists

Currently visiting a power class due to preparations for the Java exam, we basically came up to a question:
class Node{ //List node
String text;
Node next;
}
class Stringbuilder{
...
void append(String s) //attaches s
String toString() //returns the fully built String
}
public static String listToString(Node first){
//TO DO
}
Our task is to define listToString. We did an iterative method that is definitely working, but I was curious about this recursive alternative:
public static String listToString(Node first){
StringBuilder sb = new StringBuilder();
if(first == null) return "";
String result = first.text;
return result + sb.append(first.next.text).toString();
}
So the question is: Can this work?
There is nothing recursive in the listToString method you posted. It has to call itself to be recursive.
public static String listToString(Node first)
{
if(first == null) return "";
String result = first.text;
return result + " " + listToString(first.next);
}

Overriding toString method to format Linked List into string recursively

I need to turn my linked list into a string recursively. The variable is next Node and variable value is the Node's string value. The String needs to be formated so that there is a semicolon(with a space before and after) between the values. This is what I have so far..
public String toString() {
String result = "";
if (this.next == null) {//base case
return " ; " + value;
}
else {
result += this.next.toString() ;//reduction step
}
return result;
public String toString() {
String result = value;
if (next != null) {
result += " ; " + next.toString();
}
return result;
}

How do I print an Object of MyList?

Any time I try to print a MyList object I get 'User#' some hex number.
Can someone help me out with a printing function or a way to print in the main? I heard of trying to Override the toString function, but I couldn't seem to get that to work and am not sure if thats the correct thing to do.
public class MyList {
private ListElement head, tail; //Forward declaration
void add(Object value) {
if (tail != null) {
tail.next = new ListElement(value);
tail = tail.next;
}
else {
head = tail = new ListElement(value);
}
}
Object remove()
{
assert head != null; // don't remove on empty list
Object result = head.value;
head = head.next;
if (head == null) { //was that the last?
tail = null;
}
return result;
}
//Nested class needed only in the implementation of MyList
private class ListElement {
ListElement(Object value) {this.value = value;}
Object value;
ListElement next; //defaults to null as desired
}
public static void main(String[] args) {
myList anInstance = new myList();
String someValue = "A list element";
anInstance.add(someValue);
String anotherValue = "Another value";
anInstance.add(anotherValue);
}
}
The override I tried went something like this:
#Override
public String toString() {
return String.format(this.head);
}
}
You state:
The override I tried went something like this:
#Override
public String toString() {
return String.format(this.head);
}
}
That's a start, now instead of just printing the head, use a while loop to iterate through the entire list, and create a new String that contains the information from all the elements. Then return that String.
i.e.,
#Override
public String toString() {
ListElement tail = this.tail;
// or you might need to start at the head element depending on which way
// you will iterate.
String returnString = "";
// use a while loop here to go through your list
// and add pertinent info from each element to the returnString
return returnString;
}
}
Note that if you were wanting to be super-efficient, you'd use a StringBuilder to do your concatenation, however for your application, this is likely over-kill and not necessary.
Note 2: Hopefully ListElement has a toString() method, and if so, use it inside of your while loop to get each element's info.
Next iteration:
#Override
public String toString() {
String returnString = "";
ListElement currentElement = this.tail;
while (currentElement != null) {
returnString += // *** get toString() info from currentElement
currentElement = // **** reset currentElement to next element
}
return returnString;
}
}
The default toString() method prints the memory address of the object (that Hex number you're seeing).
If you want something different, you need to:
#Override
public String toString()
{
//do stuff to build a string that describes your object
//return that string you just built
}
This code is an untested implementation of the toString method. Try it out.
#Override
public String toString()
{
String myString = "";
ListElement currentElement = head;
while (currentElement.next != null)
{
if (myString.length > 0)
{
myString += ",";
}
myString += currentElement.value.toString();
currentElement = currentElement.next;
}
return myString;
}

Sorting and comparing XML from Java

I was given XML and schema files. My goal was to output all data from the XML (without duplicates) and order this list by the date of birth. Currently I got all data printed out (with duplicates) and I don't know what to do next. I've tried different things, but unsuccessfully.
HashSet will depend on the Node.equals() method to determine equality, and you're adding distinct nodes, albeit with the same underlying text. From the doc:
adds the specified element e to this set if this set contains no
element e2 such that (e==null ? e2==null : e.equals(e2))
I would extract the underlying text (String) from the Node, and a HashSet<String> will determine uniqueness correctly.
EDIT
After reading the post again I realised I need to remove dups too so:
You can use a TreeSet to impose unqiueness and sort by DOB - I presume that a person with the same first name, surname and date of birth is the same person.
First I would wrap your Node in a class that implements Comparable and that also does the getting of all those properties you have. The wrapper needs to implement Comparable as the TreeSet uses this method to decide whether elements are different (a.compareTo(b) != 0) and also how to order them.
public static final class NodeWrapper implements Comparable<NodeWrapper> {
private static final SimpleDateFormat DOB_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
private final Element element;
private final Date dob;
private final String firstName;
private final String surName;
private final String sex;
public NodeWrapper(final Node node) {
this.element = (Element) node;
try {
this.dob = DOB_FORMAT.parse(initDateOfBirth());
} catch (ParseException ex) {
throw new RuntimeException("Failed to parse dob", ex);
}
this.firstName = initFirstName();
this.surName = initSurnameName();
this.sex = initSex();
}
private String initFirstName() {
return getNodeValue("firstname");
}
private String initSurnameName() {
return getNodeValue("surname");
}
private String initDateOfBirth() {
return getNodeValue("dateofbirth");
}
private String initSex() {
return getNodeValue("sex");
}
private String getNodeValue(final String name) {
return element.getElementsByTagName(name).item(0).getTextContent();
}
public Node getNode() {
return element;
}
Date getDob() {
return dob;
}
public String getFirstName() {
return firstName;
}
public String getSurName() {
return surName;
}
public String getDateOfBirth() {
return DOB_FORMAT.format(dob);
}
public String getSex() {
return sex;
}
public int compareTo(NodeWrapper o) {
int c;
c = getDob().compareTo(o.getDob());
if (c != 0) {
return c;
}
c = getSurName().compareTo(o.getSurName());
if (c != 0) {
return c;
}
return getFirstName().compareTo(o.getFirstName());
}
#Override
public int hashCode() {
int hash = 5;
hash = 47 * hash + (this.dob != null ? this.dob.hashCode() : 0);
hash = 47 * hash + (this.firstName != null ? this.firstName.hashCode() : 0);
hash = 47 * hash + (this.surName != null ? this.surName.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final NodeWrapper other = (NodeWrapper) obj;
if (this.dob != other.dob && (this.dob == null || !this.dob.equals(other.dob))) {
return false;
}
if ((this.firstName == null) ? (other.firstName != null) : !this.firstName.equals(other.firstName)) {
return false;
}
if ((this.surName == null) ? (other.surName != null) : !this.surName.equals(other.surName)) {
return false;
}
return true;
}
#Override
public String toString() {
return "FirstName: " + getFirstName() + ". Surname: " + getSurName() + ". DOB: " + getDateOfBirth() + ". Sex: " + getSex() + ".";
}
}
So if the date of birth, surname and firstname are all equal we assume it is the same person - we return 0. It is good practice, if using compareTo in this way to make it consistent with equals so that if a.compareTo(b)==0 then a.equals(b), I have added the required equals and hashCode methods as well.
Now you can use a TreeSet in your code which will automatically sort and guarantee unqiueness:
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("file.xml"));
final Set<NodeWrapper> inimesteList = new TreeSet<NodeWrapper>();
final NodeList isa = doc.getElementsByTagName("isa");
for (int i = 0; i < isa.getLength(); i++) {
inimesteList.add(new NodeWrapper(isa.item(i)));
}
final NodeList ema = doc.getElementsByTagName("ema");
for (int i = 0; i < ema.getLength(); i++) {
inimesteList.add(new NodeWrapper(ema.item(i)));
}
final NodeList isik = doc.getElementsByTagName("isik");
for (int i = 0; i < isik.getLength(); i++) {
inimesteList.add(new NodeWrapper(isik.item(i)));
}
System.out.println();
System.out.println("Total: " + inimesteList.size());
for (final NodeWrapper nw : inimesteList) {
System.out.println(nw);
}
I have also added a toString method and used that to print the nodes - this makes the code much cleaner.
The Document approach, while seeming simpler than JAXB, is riddled with this sort of tedium. As you already have a schema I would strongly recommend that you make the move to xjc and JAXB unmarshalling - this will make this sort of stuff hundereds of times easier.
Its better to create a Java Bean (POJO) with the single node details. Override equals() and hashcode() in the same. Store all the Node data into the List of Bean. Then use LinkedHashSet to remove duplicates. Implement Comparable or use Comparator and Collections.sort() to sort the same.
Extend or encapsulate Node in another class and override equals() and hashcode() in the same. Store all the Nodes into the List of new class instance. Then use LinkedHashSet to remove duplicates. Implement Comparable or use Comparator and Collections.sort() to sort the same.

Sorted List in Java

I need to sort the list in java as below:
List contains collection of objects like this,
List list1 = {obj1, obj2,obj3,.....};
I need the final list which has "lowest value" and "repetition of name should avoid".
Ex:
List list1 = {[Nellai,10],[Gujarath,10],[Delhi,30],[Nellai,5],[Gujarath,15],[Delhi,20]}
After Sorting , I need the list like this :
List list1 = {[Nellai,5],[Gujarath,10],[Delhi,20]};
I have 2 Delhi (30,20) in my list. But I need only one Delhi which has lowest fare (20).
How to do that it in java?
Gnaniyar Zubair
If order doesn't matter, a solution is to use a Map[String, Integer], add an entry each time you find a new town, update the value each time the stored value is less than the stored one and then zip all the pairs into a list.
Almost the same as #Visage answer, but the order is different:
public class NameFare {
private String name;
private int fare;
public String getName() {
return name;
}
public int getFare() {
return fare;
}
#Override public void equals(Object o) {
if (o == this) {
return true;
} else if (o != null) {
if (getName() != null) {
return getName().equals(o.getName());
} else {
return o.getName() == null;
}
}
return false;
}
}
....
public Collection<NameFare> sortAndMerge(Collection<NameFare> toSort) {
ArrayList<NameFare> sorted = new ArrayList<NameFare>(toSort.size());
for (NameFare nf : toSort) {
int idx = sorted.getIndexOf(nf);
if (idx != -1) {
NameFare old = sorted.get(idx);
if (nf.getFare() < old.getFare()) {
sorted.remove(idx);
sorted.add(nf);
}
}
}
Collections.sort(sorted, new Comparator<NameFare>() {
public int compare(NameFare o1, NameFare o2) {
if (o1 == o2) {
return 0;
} else {
if (o1.getName() != null) {
return o1.getName().compareTo(o2.getName());
} else if (o2.getName() != null) {
return o2.getName().compareTo(o1.getName());
} else {
return 0;
}
}
}
});
}
I would do it in two stages.
Firstrly sort the list using a custom comparator.
Secondly, traverse the list and, for duplicate entries (which will now be adjacent to each other, provided you worte your comparator correctly), remove the entries with the higher values.
If you want to avoid duplicates, perhaps a class like TreeSet would be a better choice than List.
I would use an ArrayList like this:
ArrayList<Name> listOne = new ArrayList<Name>();
listOne.add(new Name("Nellai", 10);
listOne.add(new Name("Gujarath", 10);
listOne.add(new Name("Delhi", 30);
listOne.add(new Name("Nellai", 5);
listOne.add(new Name("Delhi", 20);
Collection.sort(listOne);
Then create the Name class
class name implements Comparable
{
private String name;
private int number;
public Name(String name, int number)
{
this.name= name;
this.number= number;
}
public String getName()
{
return this.name;
}
public int getNumber()
{
return this.number;
}
public int compareTo(Object otherName) // must be defined if we are implementing //Comparable interface
{
if(otherName instanceif Name)
{
throw new ClassCastException("Not valid Name object"):
}
Name tempName = (Name)otherName;
// eliminate the duplicates when you sort
if(this.getNumber() >tempName.getNumber())
{
return 1;
}else if (this.getNumber() < tempName.getNumber()){
return -1;
}else{
return 0;
}
}
}
I didn't compiled the code, it's edited here so you should fix the code. And also to figure out how to eliminate the duplicates and print only the lowest one.
You need to sweat too.

Categories