so I'm trying to figure out how to print the actual contents, not memory locations, of my array list
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class hw2redo
{
public static void main(String args[]) throws FileNotFoundException
{
//Scan file for data
GeometricObject g = null;
BufferedReader file = new BufferedReader(new FileReader("file.txt"));
Scanner diskScanner = new Scanner(file);
//Create dynamic array list
ArrayList<GeometricObject> list = new ArrayList<GeometricObject>();
//Scan data and add data to list
while(diskScanner.hasNext())
{
String geolist = diskScanner.nextLine();
g = recreateObject(geolist);
list.add(g);
}
showObjects(list);
}
private static GeometricObject recreateObject(String data)
{
GeometricObject object = new GeometricObject(data);
return object;
}
private static void showObjects(ArrayList<GeometricObject> list)
{
for(GeometricObject o : list)
System.out.println(o);
}
}
class GeometricObject
{
public GeometricObject(String data) {
// TODO Auto-generated constructor stub
}
}
So here is my code. I have tried using the toString() and Arrays.toString() but they dont seem applicable for an arraylist (I tried because they worked on my regular arrays).
The output I'm recieving is
// Output
GeometricObject#55f96302
GeometricObject#3d4eac69
GeometricObject#42a57993
GeometricObject#75b84c92
GeometricObject#6bc7c054
GeometricObject#232204a1
which is good because I'm close, I just need to figure out how to print the actual contents.
The content I'm looking for in my file.txt is
Circle,green,false,4.0
Circle,blue,false,2.0
Circle,blue,true,7.0
Rectangle,orange,true,10.0,6.0
Rectangle,green,false,5.0,11.0
Rectangle,red,true,14.0,12.0
Any help would be much appreciated. Thanks!
You need a toString method in your class:
class GeometricObject
{
private String data;
public GeometricObject(String data) {
this.data = data;
}
#Override
public String toString() {
return data;
}
}
Without the Override, you are using Object.toString(). Object's toString prints out the class name and the hashcode of the object, as you have observed.
System.out.println(o);
When you call System.out.println, That apparently calls the toString() method of your Object. Since you didn't ovveride toString(), it calls the default implementation. Ovveride toString() method to print as you wish.
public class GeometricObject {
....
#Override
public String toString() {
// return string representation of your object.
}
}
To starts with :What is the best standard style for a toString implementation?
Related
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 3 years ago.
Can someone help me to serialze an object into a string? The result of my code is a bit weird, I need to get a toString(); methode or something with which i can serialze an object into a string but I dont know any.
Thanks for the help
results with getString -> only "null"
result without getString(); -> Fruit#4dd8dc3, Fruit#6d03e736, Fruit#568db2f2, Fruit#378bf509, Fruit#5fd0d5ae,
Fruit#2d98a335, Fruit#16b98e56, Fruit#7ef20235"
import java.io.Serializable;
public class Fruit implements Comparable<Fruit>,Serializable{
String getString;
String name;
int gewicht;
public String getString() {
return this.getString;
}
public Fruit(String name, int gewicht) {
this.name=name;
this.gewicht=gewicht;
}
public int compareTo(Fruit otherFruit) {
if(this.gewicht < otherFruit.gewicht)
return -1;
if(this.gewicht>otherFruit.gewicht)
return 1;
return 0;
}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.TreeSet;
public class FruitTree {
public static void main(String[] args) {
TreeSet<Fruit> fruitTree = new TreeSet<Fruit>();
fruitTree.add(new Fruit("Kiwi",5));
fruitTree.add(new Fruit("Kirsche",1));
fruitTree.add(new Fruit("Ananas",75));
fruitTree.add(new Fruit("Zitrone",15));
fruitTree.add(new Fruit("Grapefruit",44));
fruitTree.add(new Fruit("Banane",55));
fruitTree.add(new Fruit("Kirsche",2));
fruitTree.add(new Fruit("Kiwi",8));
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO.txt"));
Iterator<Fruit> it = fruitTree.iterator();
while(it.hasNext()) {
oos.writeObject(it.next());
}
oos.writeObject(null);
ObjectInputStream ois = new ObjectInputStream (new FileInputStream("IO.txt"));
Object readObject=null;
TreeSet<Fruit> deserializedFruits= new TreeSet<Fruit>();
do {
readObject=ois.readObject();
if(readObject !=null)
deserializedFruits.add((Fruit) readObject);
}
while (readObject!=null);
it=deserializedFruits.iterator();
while(it.hasNext()) {
System.out.println(it.next().getString());
ois.close();
oos.close();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Can someone help me to serialze an object into a string? The result of my code is a bit weird, I need to get a toString(); methode or something with which i can serialze an object into a string but I dont know any.
Thanks for the help
Adding implements Serializable to your class will not override default Object.toString implementation - that's not how Java works (btw this default implementation will actually provide you what you got - for example Fruit#5fd0d5ae - that's how it works)
what you need to do is to override toString by yourself - for example
public class Fruit implements Comparable<Fruit>,Serializable {
// ...
#Override
public String toString() {
return "name: " + this.name + ", gewicht: " + String.valueOf(this.gewicht);
}
}
or to use some existing tool that will generate this method for you (like lombok), or even better that will allow you to serialize your class object to some common format like JSON or XML (for this take a look at gson or Jackson)
I'm trying to Parse the static variable value from the JAVA file. But couldn't be able to parse the variable.
I've used JavaParser to Parse the code and fetch the value of variable. I got success in fetching all other class level variable and value but couldn't be able to parse the static field.
The Java File looks like ...
public class ABC {
public string variable1 = "Hello How are you?";
public boolean variable2 = false;
public static String variable3;
static{
variable3 = new String("Want to Fetch this...");
}
//Can't change this file, this is input.
public static void main(String args[]){
//....Other Code
}
}
I'm able to parse the all variables value except "variabl3". The Code of Java File looks like above Java Code and I need to Parse "variable3"'s value.
I've done below code to parse the class level variable...
import java.util.HashMap;
import java.util.List;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
public class StaticCollector extends
VoidVisitorAdapter<HashMap<String, String>> {
#Override
public void visit(FieldDeclaration n, HashMap<String, String> arg) {
// TODO Auto-generated method stub
List <VariableDeclarator> myVars = n.getVariables();
for (VariableDeclarator vars: myVars){
vars.getInitializer().ifPresent(initValue -> System.out.println(initValue.toString()));
//System.out.println("Variable Name: "+vars.getNameAsString());
}
}
}
Main Method ...
public class Test {
public static void main(String[] args) {
File file = new File("filePath");
CompilationUnit compilationUnit = null;
try {
compilationUnit = JavaParser.parse(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HashMap<String, String> collector = new HashMap<String, String>();
compilationUnit.accept(new StaticCollector(), collector);
}
}
How could I parse the value of "variable3", which is static and value assigned inside static block? There might be other variable in the code but I need to find value of particular variable value (in this case Variable3).
Am I doing something wrong or i need to add some other way, please suggest.
Inspecting the AST as something that's easily readable, e.g., a DOT (GraphViz) image with PlantUML is a huge help to solve this kind of problem. See this blog on how to generate the DOT as well as other formats.
Here's the overview, with the "variable3" nodes highlighted (I just searched for it in the .dot output and put a fill color). You'll see that there are TWO spots where it occurs:
Zooming in on the node space on the right, we can see that the second sub-tree is under an InitializerDeclaration. Further down, it's part of an AssignExpr where the value is an ObjectCreationExpr:
So, I adapted your Visitor (it's an inner class to make the module self contained) and you need to override the visit(InitializerDeclaration n... method to get to where you want:
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.InitializerDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;
public class Test {
public static void main(String[] args) {
File file = new File("src/main/java/ABC.java");
CompilationUnit compilationUnit = null;
try {
compilationUnit = StaticJavaParser.parse(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HashMap<String, String> collector = new HashMap<String, String>();
compilationUnit.accept(new StaticCollector(), collector);
}
private static class StaticCollector extends
VoidVisitorAdapter<HashMap<String, String>> {
#Override
public void visit(FieldDeclaration n, HashMap<String, String> arg) {
List<VariableDeclarator> myVars = n.getVariables();
for (VariableDeclarator vars: myVars){
vars.getInitializer().ifPresent(initValue -> System.out.println(initValue.toString()));
//System.out.println("Variable Name: "+vars.getNameAsString());
}
}
#Override
public void visit(InitializerDeclaration n, HashMap<String, String> arg) {
List<Statement> myStatements = n.getBody().getStatements();
for (Statement s: myStatements) {
s.ifExpressionStmt(expressionStmt -> expressionStmt.getExpression()
.ifAssignExpr(assignExpr -> System.out.println(assignExpr.getValue())));
}
}
}
}
Here's the output showing additionally variable3's initialization in the static block:
"Hello How are you?"
false
new String("Want to Fetch this...")
I am pretty new for java.I am trying to make a project that get class names,field names from desired .java file(HelloOOPP.java).
I get class names successfully but i have a problem on field names.
It returns following text instead of HelloOOPP class field names(Output)(I expected to get x and y fields):
Class name:HelloOOPP
Fields:
NODE_BY_BEGIN_POSITION
ABSOLUTE_BEGIN_LINE
ABSOLUTE_END_LINE
SYMBOL_RESOLVER_KEY
App.java File:
package com.app;
import java.io.File;
import java.io.FileNotFoundException;
public class App
{
public static void main(String[] args) throws FileNotFoundException {
System.out.println(GetTypes.parseClassname(new File("C:\\HelloOOPP.java")));
}
}
GetTypes.java File:
package com.app;
import com.github.javaparser.*;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.*;
import java.io.*;
import java.lang.reflect.Field;
public class GetTypes {
public static String parseClassname(File filename) throws FileNotFoundException {
FileInputStream fin = new FileInputStream(filename);
CompilationUnit cu = JavaParser.parse(fin);
StringBuilder build=new StringBuilder();
for (TypeDeclaration type : cu.getTypes())
{
if (type.isClassOrInterfaceDeclaration())
{
build.append("Class name:");
build.append(type.getName());
build.append("\n");
build.append("Fields:");
build.append("\n");
build.append(Get_Fields(type));
}
}
return build.toString();
}
private static StringBuilder Get_Fields(TypeDeclaration c) //Get all field names
{
Field[] fields = c.getClass().getFields();
StringBuilder str=new StringBuilder();
for(int i=0;i<fields.length;i++)
{
str.append(fields[i].getName());
str.append("\n");
}
return str;
}
/*
private int Count_Fields(TypeDeclaration c)
{
}*/
}
HelloOOPP.java file:
public class HelloOOPP
{
public int x;
public int y;
}
You are mixing Javaparser and classical reflection.
When you write
Field[] fields = c.getClass().getFields();
, what you get is the fields from the TypeDeclaration class, not the HelloOOPP class (that's why you see unexpected field names like ABSOLUTE_BEGIN_LINE).
Based on the question How to get class level variable declarations using javaparser ?
, your method could look like :
private static StringBuilder Get_Fields(TypeDeclaration c) //Get all field names
{
List<BodyDeclaration> members = c.getMembers();
StringBuilder str=new StringBuilder();
if(members != null) {
for (BodyDeclaration member : members) {
//Check just members that are FieldDeclarations
FieldDeclaration field = (FieldDeclaration) member;
str.append(field.getVariables().get(0).getId().getName());
str.append("\n");
}
}
return str;
}
I have an empty interface called Data which is implemented by classes DataOne and DataTwo.
I then have a class called DataHolder which contains a Data object.
It looks something like this:
public class DataHolder() {
public Data data;
}
public class DataOne() {
public int importantData;
public int getImportantData() {
return importantData;
}
public int setImportantData(int importantData) {
this.importantData = importantData;
}
}
public class DataTwo() {
public int notSoImportantData;
}
Let's say theres a function which takes a DataHolder object and does some operation on the importantData integer.
public void calculateImportantData(DataHolder dh) {
int importantData = 1234567890;
dh.data.setImportantData(importantData);
}
How can I be sure that the DataHolder contains a DataOne object, without typecasting?
How about:
public class DataHolder<T extends Data> {
public T data;
}
and in your code you will have:
public void calculateImportantData(DataHolder<DataOne> dh) {
int importantData = 1234567890;
dh.data.setImportantData(importantData);
}
and I assume you meant DataOne and DataTwo to implement Data.
first of all , I tweaked your code a little bit ,
1- I created an Interface , Data , containing some random method someMethod() :
package main.interfaces;
public interface Data {
int myData = 0;
public void someMethod();
}
2- then , I created 2 classes called DataOne and DataTwo :
Class DataOne: ( notice how i added the important business method setImportantData() here , this provides total Encapsulation of your work).
package main;
import main.interfaces.Data;
public class DataOne implements Data{
public int importantData;
public int getImportantData() {
return importantData;
}
public void setImportantData(int importantData) {
this.importantData = importantData;
}
#Override
public void someMethod() {
System.out.println("here in DataOne!... ");
}
public void calculateImportantData(int importantData) {
// int importantData = 1234567890;
setImportantData(importantData);
}
}
Class DataTwo:
package main;
import main.interfaces.Data;
public class DataTwo implements Data{
public int notSoImportantData;
#Override
public void someMethod() {
System.out.println("here in DataTwo!...");
}
public void calculateUsualData(DataTwo d2) {
d2.someMethod();
}
}
after that , using Factory Design Pattern ... I created this DataFactory class:
package main.factory;
import main.DataOne;
import main.DataTwo;
import main.interfaces.Data;
public class DataFactory {
public static Data getData(String dataType){
if(dataType == null){
return null;
}
if(dataType.equalsIgnoreCase("DATAONE")){
return new DataOne();
} else if(dataType.equalsIgnoreCase("DATATWO")){
return new DataTwo();
}
return null;
}
}
now , back to your problem solution , I used DataHolder , encapsulating DataFactory here:
package main.holder;
import main.factory.DataFactory;
import main.interfaces.Data;
public class DataHolder {
Data data;
public DataHolder(String dataType){
data = DataFactory.getData(dataType);
}
public Data getData(){
return data;
}
}
now , try to run the application , I added some comments that will appear on your console , and I hope they will be helpful :)
package main.run;
import main.DataOne;
import main.DataTwo;
import main.holder.DataHolder;
import main.interfaces.Data;
public class main {
public static void main(String[] args) {
// lets assume user of the method passed a DataOne Object, you can
// manage it by changing the value of flag string
String flag = "DataOne";
DataHolder dataHolder = new DataHolder(flag);
if (dataHolder.getData() instanceof DataOne) {
System.out
.println("you have a DataOne object , but a Data reference");
System.out
.println("/nso , you need to create a 'reference' to DataOne to work on that object ...");
} else if (dataHolder.getData() instanceof DataTwo) {
System.out
.println("you have a DataTwo object , but a Data reference");
} else {
System.out
.println("you dont have a DataOne nor DataTwo references , it is a "
+ dataHolder.getData().getClass() + " object!");
}
System.out
.println("in order for the compiler to pass the following test , you must cast he RHS ( right hand side ) to match the LHS (left hand side)");
// in order for the compiler to pass the following test , you must cast
// the RHS ( right hand side ) to match the LHS (left hand side)
DataOne d1 = (DataOne) dataHolder.getData();
// in case you wanted to test DataTwo scenario
//DataTwo d2 = (DataTwo) dataHolder.getData();
System.out.println("if you didnt do that , you can make it a Data Object , but you will not be able to access the method 'getImportantData()' created in DataOne");
Data data = dataHolder.getData();
}
}
(note , here the program structure is : you select the type of the data before you start the application , stored in the "flag" variable inside the main method. after that , a call to DataHolder method will be made , after that , you can check the returned object and check if it is what u specified earlier. if you want it to be a little complicated , you can pass the object type in the DataHolder's constructor , and do the check from there , I didn't want to do it just for simplicity. Good Luck)
I want to remove elements from an arraylist with the method:
public static String removeOldestItem(ArrayList<String> theList)
and to write the removed elements to a text file using this method:
public static void addItem(ArrayList<String> theList, String s)
So far I have:
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList <String> s = new ArrayList<> (4);
s.add("Knock knock.");
s.add("Who's there?");
s.add("*very long pause....*");
s.add("Java");
try {
FileWriter fos = new FileWriter("list_contents.txt");
PrintWriter out = new PrintWriter(fos);
for (int i = 0; i < s.size(); i++) {
out.write(String.valueOf(s.get(i) ) );
out.write("\r\n");
}
out.close();
} catch (Exception e) {
}
}
}
The second method should place the String “s” into the passed list “theList”. The first method should remove the item that has been in the list the longest and return that item to the caller.
I'm having trouble understanding how to implement the methods.
Any thoughts?
I'm not aware of a removeOldestItem method on ArrayList, however linked lists and linked hash maps have removeEldestEntry. It is generally overridden to produce a cache with some sort of smart pruning.
Is your goal to extend ArrayList and an OutputStream by adding a couple convenience methods?