Accessing a list in a Java object - java

I have been trying to figure this for 1hr30 now and its too confusing for what seems like a really simple problem so I came here to ask.
I send a get request to a 3rd party API to get anime (movie) details as xml.
I store these in a class Ann.java that was automatically generated by netbean's JAXB xml bindings from a sample xml response.
Originally the xml file I used returned only a single anime entry so I could use
String output = gt.fetchMovie().getAnime().getName();
Where gt is my web service. This would print the name of the anime to my IDE.
I changed the setup so that the 3rd party API response gives me multiple anime results instead of just one. I now search for "evangelion" and get 3 results.
However, the new schema of the xml and java class means that attributes are stored as lists. E.g. if I want to access an anime's getName it is within this structure:
public class Ann {
protected List<Object> animeOrManga;
public List<Object> getAnimeOrManga() {
if (animeOrManga == null) {
animeOrManga = new ArrayList<Object>();
}
return this.animeOrManga;
}
public String getName() {
return name;
}
I have been trying to figure out how to return getName but can't find anything that explains what I want to do. I'm not smart enough to just "figure this out" and have been 1hr30 trial and error already.
I know I want to do something like this but guessing the syntax is impossible and everything just goes red, or cannot find symbol, or whatever.
List<Object> = gt.fetchMovie().getAnimeOrManga();
For each (list object)
getName();
Thankyou for reading!

how about create a class that has name attribute like
public class Animal {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
then you can use with
List<Animal> animeOrManga = gt.fetchMovie().getAnimeOrManga();
then you can use with each.

The pseudocodish you provided can be written in Java as follows:
List<Ann> list = new ArrayList<Ann> // You want the list as specific as possible
list.clone(gt.getAnimeOrManga());
for(Ann listObject : list) { // For each loop
listObject.getName();
}
What is used is a for-each loop, which is exactly what is sounds: for each thing in this list do this.
The clone() method takes an arraylist and copies it into the new one.
See here: How do I copy the contents of one ArrayList into another?

Related

Create JSON File Serializing the class in Java

I have the following class:
public class PDFValues {
private String value;
private int xPos;
private int yPos;
public PDFValues(){
}
public PDFValues(String value, int x, int y){
this.setValue(value);
this.setX(x);
this.setY(y);
}
public void setValue(String value){
this.value = value;
}
public void setX(int x){
this.xPos = x;
}
public void setY(int y){
this.yPos = y;
}
public String getValue(){
return this.value;
}
public int getX(){
return this.xPos;
}
public int getY(){
return this.yPos;
}
}
And then I want to do this:
public class PDFtoJSONTest {
public static void main(String[] args) {
List<PDFValues> listaElementos = new ArrayList<PDFValues>();
listaElementos.add(new PDFValues("Anubis Lockward Botello",
new Integer(100), new Integer(633)));
....more code
}
}
What I want to do, is save all the PDFValues in the ArrayList, as a JSON file, but I don't know how to make it automatic, I thought of Serializing the object or something, but I can't find a solution to this and I'm not sure how I could make the PDFValues object serializable.
I want to do this to save those values in a JSON file and then use them as properties to generate a PDF file, I'm using PDFBox for the generation of the PDFs files and SimpleJSON for the .json ones.
I'm working on a project where I'd have to generate thousands of pdf files out of some processed data. I've already managed to parse the data which consists of about 500+ MBs of text and holds around five thousand account statements which need to be generated as PDFs.
The thing is, that seeings as the Text data is generated in PDFs, one needs to indicate the position of the starting character in a string to PDFValues, to generate a PDFTextInfo object and then add it to the PDF, the file would need to contain images and text and other stuff.
Note: If there's a better way to accomplish what I'm trying to do, I'm open to suggestions, but I'd also like an answer to what I'm trying to do, and know if it would work or not, and why for both cases.
I'd like to make my code as fast as possible, right now I'm able to process the whole TXT file from RAW to mostly clean data in under 2 minutes and I know it might be optimized but right now that's not the point :D
I'd like to generate the PDFs files as fast as possible, but I've been working with that project in Java for like 1 1/2 months now, and I've only learned about JSON and PDF file generation in the past week...it's been three days of working on the JSON file and I'm a bit lost.
Here's an example of the file output for the JSON file that I'm trying to accomplish, this one I generated it manually and I managed to read and process the file, now I'm trying to generate it automatically:
{
"Header": {
"FullName":
{
"Name":"Anubis Lockward Botello",
"Horizontal":180,
"Vertical":633
},
..... more elements .....
}
}
As you can see, I'm trying to divide the elements on the pdf files as if they were panels, like HEADER, BALANCES, TRANSACTIONS and stuff, and build the PDF file as if they were pieces of a puzzle, but right now I'm trying to "build" the name element on the header.
I would guess there is a better way to do build PDF files than writing and then re-reading a file, but I can provide one answer for your JSON question.
Use the Apache commons-lang3 library and look into ToStringBuilder. You can then define a toString() method on your object and use the built-in ToStringStyle.JSON_STYLE format. You'd then have to wrap your list of PDFValues in some other object that can store a PDFValue for Header, FullName, etc..
#Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
.append("Name", value)
.append("Horizontal", xPos)
.append("Vertical", yPos)
.toString();
}
I should note that you could pull in Jackson or similar libraries, annotate your objects with the required JsonProperty annotations and use the library to serialize your object to JSON as you would for REST or similar. But, for a simple use case like yours, the ToStringBuilder is simple and effective.
OK, I managed to get this far thanks to JudgingNotJudging, what I did was taking his answer and applying a Decorator Pattern to the object, so that I have a PDFValue, that's inside a PDFElement, that's part of a PDFContainer, so it goes like this:
Header: (this is our PDFContainer)
FullName: (so, Header HAS-A FullName element)
PDFValue: (and FullName HAS-A a PDFValue, that has the Name or value to be shown, and the X and Y coordinates inside the PDF)
Here's the code:
The PDFValue class is still the same, and I added the overridden toString() method according to JudgingNotJudging's answer.
public class PDFValuesDecorator extends PDFValues{
}
In PDFValuesDecorator we don't do anything, we're just going to extend PDFValues so that we have the correct type of the class we want to add behavior to, and still get a common type for all the different classes we might create this way.
public class PDFElement extends PDFValuesDecorator {
private PDFValues pdfValue;
private String elementID;
public PDFElement(PDFValues pdfValue, String elementID){
this.pdfValue = pdfValue;
this.elementID = elementID;
}
#Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
.append(elementID, pdfValue.toString())
.toString();
}
}
In the constructor we save the instance of the object we're trying to "wrap" so that we can "add" something to it. In this case, we're adding an ID for the element and we're modifying the toString() method of the element to also include the toString() method of the PDFValue, so that they both show both of their values in the appropriate order.
Finally, here's my main method:
public class PDFtoJSONTest {
public static void main(String[] args) {
List<PDFValues> listaElementos = new ArrayList<PDFValues>();
PDFValues name =
new PDFValues(
"Anubis Lockward Botello",
new Integer(100),
new Integer(633)
);
PDFElement fullName = new PDFElement(name, "FullName");
PDFElement header = new PDFElement(fullName, "Header");
listaElementos.add(header);
for(PDFValues value : listaElementos){
System.out.println("Valor: " + value.toJSONString());
}
}
}
As you can see, the first thing I do is create an ArrayList of PDFValues, then I create a single object for the name value, then that name is wrapped inside the FullName element, and then that's stored inside a Header element. As you can see, I can pass around the List object and do with it whatever I want.
And also, I could create other PDFElements like images and stuff, and I can save all of them inside the ArrayList and pass them around and then when I want to save them, I just have to call the toString method once and I would get the correct output, btw, here's the resulting value from the JSON string:
Valor: {"Header":"{"FullName":"{"Name":"Anubis Lockward Botello","Horizontal":100,"Vertical":633}"}"}

Complex Data structure in Java multi-level collections (lists) within one class

I am relatively new to Java. I have been struggling to define a class that meets my needs. Searching on this site or google did not have probably because the question is so specific. Any help is appreciated!
Ideally the class (lets call it Filer) would have:
Name (string)
Volumes (Collection/list of Strings: 0 -100)
Each Volume, in turn, will have:
A. Name (string)
B. Servers_Permed (another collection/list of Strings: 0-40)
Once I can get the class defined, I will do ok with defining getters and setters to use it, but so far I have failed to defined the class without getting totally lost :-)
Thanks!
It seams that your description is not correct.
You need a class Filer with:
name (String)
volumes (list of Volume) (not strings as you asked, because you explained differently on the second part of the question, it is evident that you need a list of Volume and not a list of String)
And a second class Volume with:
Name (string)
Servers_Permed (list of strings)
So you need a data structure like the following:
public class Volume {
private String name;
private List<String> serversPermed; // Changed the name to a name more adherent to standard guidelines
...
}
public class Filer {
private String name;
private List<Volume> volumes;
...
}
well, lay it out piece by piece.
First, you have Volume (not sure how volumes could be "Collection/list of Strings: 0 -100" and have the following properties):
public class Volume {
String name;
List<String> servers_permed;
}
Now you have Filer:
public class Filer {
String name;
List<Volume> volumes;
}
you will have to add the necessary constructors, getters/setters.
Both of the answer given above worked beautifully (they are almost the same anyway).
Thank you, Davide and DBug!

How to send array as POST parameter/payload to webservice in Android using REST

Im using REST in my webservice. This is the example payload/parameter i sent when i test my webservice using advance rest client, with form content type (this is the RAW type):
child_id%5B%5D=1&user_id=15&group_id=1&custom=&time=17%3A17%3A00&date=&child_id%5B%5D=2
Where child_id%5B%5D in RAW means child_id[] in the form, so i send an array of child_id (left most and right most in above form). Things are fine here.
The problem occured when i tried to implement this to the Android apps, where i POST those payload/parameter using a HashMap. HashMap cant store two values under the same key, so i cant do something like :
map.put("child_id[]", 1);
map.put("child_id[]", 2);
The latest put will overwrite the earlier put, so the Android apps will only send 2 as value of the child_id.
What should i do? Thanks for your help
You Could add index to the array as follows.
map.put("child_id[0]", 1);
map.put("child_id[1]", 2);
You have a few options for solving this. The easiest would be to create a class to act as a container for your parameters, and store those in an ArrayList
public class Parameter {
private String key;
private String value;
// Getters, setters, other stuff.
}
Which you would then store in an ArrayList
You could also make a class to act as a parameter builder of sorts. You might do something like this:
public class Parameters {
private ArrayList<String> keys = new ArrayList<>();
private ArrayList<String> values = new ArrayList<>();
public void add(String key, String value) { ... }
public ArrayList<String> getKeys() { ... }
public ArrayList<String> getValues() { ... }
}
The second option requires a bit more code but adds some extra flexibility and should make for a cleaner API.
Alternatively, as you mentioned in your own comment, you have the option of using a Map<String, ArrayList<String>>. Which would also work very well in place of the ArrayLists in the above example.

Benefits of factoring a new class vs string values for elements in a Set

This is more of a design question with implications for code simplicity vs. performance.
Lets say you want to make sure a set of values for a given user id are the same between two systems. The example here is to check that a student id has the same number of course enrollments in System A and System B.
For this we create:
List<String> studentList = new ArrayList<String>();
Set<String> sysAEnrollments = new HashSet<String>();
Set<String> sysBEnrollments = new HashSet<String>();
private Map<String, String> badEnrollList = new HashMap<String, String>();
And fill them appropriately, given a list of student ids(studentList):
studentList = getCurrentStudentList();
for (String id : studentList){
sysAEnrollments = getSysAEnrollments(id);
sysBEnrollments = getSysBEnrollments(id);
if (!sysAEnrollments.containsAll(sysBEnrollments)){
badEnrollList.put(id, getBadEnrollmentsById(id, sysAEnrollments, sysBEnrollments));
}
}
Question: What should the method 'getBadEnrollmentsById' return?
Either a concatenated string with enough meaning so it can just be printed out.
Or have a new object, for example another collection with the list of course ids that could be used for further processing but harder to use for printed output.
Is it worth designing thoroughly all expected objects or replace some of them with concatenated strings for clarity and performance?
NOTES:
System A is preferred as the authoritative source
Output from getBadEnrollmentsById should have all courses and flag those missing in system B.
PROPOSED SOLUTION: (2012-SEP-14)
EDIT (2012-SEP-17): Updated the Course class to include hashCode and equals
As suggested by user351721 I continued modelling the remaining objects that match the expected results/requirements.
Slight changes made a big difference and allowed me to go over this design flaw and finish with the implementation.
The revised collections are:
List<String> studentList = new ArrayList<String>();
Enrollment sysAEnrollments;
Enrollment sysBEnrollments;
Map<String, List<String>> badEnrollList = new HashMap<String, List<String>>();
And we populate the Enrollments:
for (String id : studentList){
sysAEnrollments = getSysAEnrollments(id);
sysBEnrollments = getSysBEnrollments(id);
if (!sysAEnrollments.getCourses().containsAll(sysBEnrollments.getCourses())){
List<String> missingCourses = getProblemEnrollmentListById(id, sysAEnrollments, sysBEnrollments);
badEnrollList.put(id, missingCourses);
}
}
So for now the output can be printed from badEnrollList by getting at each ArrayList and printing the course names. A course name with a * will mean that it's missing in sysB.
The Enrollment class looks like this:
public class Enrollment {
private Set<Course> courses = new HashSet<Course>();
public void setCourses(Set<Course> courses){
this.courses = courses;
}
public Set<Course> getCourses(){
return this.courses;
}
}
And the Course class ended up like this:
public class Course {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
// Must override hashCode() and equals()
#Override
public boolean equals(Object o){
if (o == this)
return true;
if (!(o instanceof Course))
return false;
Course c = (Course) o;
return c.id.equals(this.id) && c.name.equals(this.name);
}
#Override
public int hashCode(){
// Magic numbers as shown on Joshua Bloch's book "Effective Java" 2nd Edition, p.48
int result = 17;
result = 31 * this.id.hashCode();
result = 31 * this.name.hashCode();
return result;
}
}
The changes might look subtle but the important clue is that Enrollments are not a collection of strings, Enrollments are a collection of Courses AND each Course has a name and a availability property. They don't seem to do much but by using them I am defining the objects that I'm working with and documenting how these classes can be reused in the future.
"Growing Object-Oriented Software, Guided by Tests" addresses this question: chapter 7, "Value Types". Worth reading. An excerpt:
The more code we write, the more we’re convinced that we should define types to represent value concepts in the domain, even if they don’t do much. It helps to create a consistent domain model that is more self-explanatory. If we create, for example, an Item type in a system, instead of just using String, we can f ind all the code that’s relevant for a change without having to chase through the method calls
concatenated strings
would mean you have to define a pattern and corresponding set of valid strings and implement validation and translation to entity classes. Providing an interface or class would make it easier to update your code in a year or so, not to mention other programmers that might work with your application. Why not store student, enrollment or course objects in badEnrollList? How do these objects look like and what do you want to do with them?
In general: Yes, designing thoroughly all expected objects is worth it.
I feel that a collection, such as List<String> would be a desirable return value. This allows you to more efficiently capture multiple discrepancies between the two sets, and process the missing courses in your second object more intuitively. Printing the list wouldn't be that hard, either - depending on how you wished to convey the information.
It's also worth mentioning that the .equals() method for Set is a cleaner and more intuitive way to ensure equivalence between two sets.
Instead of using all these sets and maps, I'd use Plain Old Java Objects (POJOs) that reflect the actual business objects in question. From what you've indicated, you have Students who have an id of some sort, and who are enrolled in classes on System A and on System B. I would build up a set of Student objects defined like so:
public class Student {
private String id;
private List<String> enrollmentsA;
private List<String> enrollmentsB;
// appropriate getters and setters
}
Depending on if you want to do anything else with Classes, it may even be preferable to create some form of EnrolledClass object to represent that too.
Within the students class, I'd then have a method that would determine the "bad" enrollments. If all that you want to do with this data is generate an email message, it may even be as simple as a String:
public String getBadEnrollmentsMessage() {
List<String> enrolledBoth = getCommonEnrollments();
List<String> enrolledOnlyA = getAOnlyEnrollments();
List<String> enrolledOnlyB = getBOnlyEnrollments();
StringBuilder output;
// format the contents of the above lists into output
// format should be however you want it in the email.
return output.toString();
}
Then you could have a map of Students to email enrollments messages:
HashMap<Student, String> studentEmails;
for (Student s : allStudents) {
studentEmails.put(s, s.getBadEnrollmentsMessage());
}
Of course, if you have a method like getBadEnrollmentsMessage(), I'm not even sure you need the Map of students and strings in the first place. Frankly you could just create a sendEnrollmentEmail method, pass in a Student, and extract the message via getBadEnrollmentsMessage() right there.

Find items by property in JLIST

I have a JList peopleList populated with a objects of Person class
class Person
{
private String name;
private String age;
private void setName(String value)
{
name = value;
}
private String getName()
{
return name;
}
}
Current to find a person with name I do
public boolean personByNameExists(String name)
{
for(int index = 0 ; index < peopleList .getModel().getSize() ; index ++)
{
Person pl = (Person) peopleList .getModel().getElementAt(index);
if( p1.getName().equals(name))
{
return true;
}
}
}
I am wondering if there is way to do the same operation with out going through the whole list. I am from .Net back ground and in C# I would use LINQ is there something similar in Java?
It depends a bit on the use-case. If you just want to find an entry on the model side, you can keep looping over your ListModel, or loop over the data structure behind the ListModel which can be a regular List implementation, and then you can use the methods suggested by haylem.
If you want to search on your JList, and present the search result visually to the user (for example highlight them and scroll to the relevant entry) I would highly recommend taking a look at the SwingX project which supports this out-of-the-box
You're looking for a typical filter functionality.
I'd recommend you look at Google Guava's:
Collections2.filter(Collection, Predicate),
Iterables.filter(Iterable, Class),
or Iterables.filter(Iterable, Predicate)
You can find more info here or even look at this SO question (your question is a duplicate):
filter and sort list using google collections
Update: As kleopatra made me realize, you might be using a normal ListModel.
You could specifiy a custom model when creating your JList, that either:
implements a Collection or Iterable interface,
or provides a method to return a view of the data filtered by the property you want.

Categories

Resources