I am trying to create an array of a class within a class so that I can have multiple sets of the inner class. However because I cannot create an empty an array in Java, I was wonder what's the best way to set this up. I know I can just define an array that is bigger than I would ever use but I feel that kind of sloppy programming.
Here's the important part of the 2 classes:
public class xmldata {
String Barcode;
String First;
String Last;
String Phone;
String Email;
String md5sum;
String zipfile;
picture_data[] pics;
...
public class picture_data {
static String filename;
static String directory;
As you can see, I to have an array of picture_data in xmldata. I have seen some stuff using lists but the examples are different and I am not sure I understand how to apply it in my case.
Here's the code I used to try and populate the arrays.
xmldata data = new xmldata();
ResultSet pictures=db.query("select * from pictures where barcode=?",barcode);
int i = -1;
while (pictures.next()) {
++i;
data.pics[i].setdirectory(pictures.getString("path"));
data.pics[i].setfilename(pictures.getString("filename"));
}
Any suggestions would be appreciated.
Modern idiomatic Java doesn't use raw Arrays or Vector either, it uses type safe List implementations.
Also picture_data and xmldata are not idiomatic naming convention for classes in Java, it should be PictureData and XMLData. I would challenge the semantics of a class called PictureData or XMLData as well.
A correct solution would be something like
List<PictureData> list = new ArrayList<PictureData>();
Understanding how to work with the Collections framework in Java is a fundamental requirement to be productive. Type safe Lists are a core component to writing real Java code.
If your array's size is going to be dynamic, then use lists inside and an ArrayList precisely. This way, you don't have to take care about size because it's treated internally.
Create an object of picture_data and add it into a ArrayList of picture_data
Then convert that arraylist into an array
Convert ArrayList<String> to String[] array
http://www.java-tips.org/java-se-tips/java.lang/how-to-convert-an-arraylist-into-an-array.html
Best option would be to use lazy initialized ArrayList
public class Xmldata {
List<picture_data> pics;
public void addPics(picture_data data) {
if(pics == null) pics = new ArrayList<picture_data>();
pics.add(data);
}
}
Here the pics list will only be created if the picture_data type objects are added to the Xmldata class
Related
I am using type conversion given below in my project.
**
ArrayList<Object> arr=new ArrayList<Object>();
String str=arr.toString();
**
I want to convert field str back into ArrayList<Object> type.
How to go through?
thanks for Help
You ought to be using the Serializable interface, ObjectOutputStream / ObjectInputStream and byte[] to String conversion such as DatatypeConverter.parseBase64Binary / DatatypeConverter.printBase64Binary
toString() is a protocol. It is defined to produce some string or another. It is not defined to produce a string reversible to an object. Many classes toString methods are designed to produce human readable results, which are nearly guaranteed to not be reversible.
The Java technology universe contains a number of mechanisms for serializing objects into bytes that can be stored or transmitted and then deserialized into objects. These include the built-in Java Object Streams, the build-in Java JAX-B XML marshal/unmarshaling technologies, and then open-source alternatives just as Jackson for mapping to and from Json or Yaml, and many others.
The only way to do this, is to Override the toString() method of the Object in your ArrayList. Say your object has 2 attributes: int size and String name. Your constructor would possible be
public YourObject(int size, String name){
this.size = size;
this.name = name;
}
Now you override your object:
#Override
public String toString(){
return Integer.toString(this.size) + "#" + this.name;
}
In order to create the object again, you will also need another constructor or setter:
public YourObject(String attributes){
String[] parts = attributes.split("#");
this.size = Integer.parseInt(parts[0]);
this.name = parts[1];
}
To go from object to string and back:
List<YourObject> arr; //Initialise this array
List<String> arrStrings = new ArrayList<String>();
//Convert to list of strings
for (YourObject yourObject : arr){
arrStrings.add(yourObject.toString());
}
//Convert it back
List<YourObject> yourObjects = new ArrayList<YourObject>();
for (String converted : arrStrings){
yourObjects.add(new YourObject(converted));
}
If you wish to use a native object, create your own object and extend the native.
Other than that, there is no way to do what you want. And note that this is very prone to error! So be sure to check for length of strings, sizes of arrays and whatnot.
I have following lines of code:
private ArrayList<wordClass>[] words;
and
public class wordClass {
public String wordValue = null;
public int val = 0;
public boolean used = false;
}
Is there anyway I can access wordValue, val, and used via words? Like words[5].val? I know I can do that if they are just in an array of wordClass, but I want a dynamic array to make it easier to add and subtract from the array.
And yes, I know the values should be private. Just don't want to write getters and setters yet.
Thanks.
Do you really want an Array of an ArrayList?
It doesn't seem correct.
In Arrays, you use [] to access (words[0]).
In ArrayLists, you should use words.get(0).
The way you have coded, you should use: words[0].get(0).val to get the very first value.
But I recommend you to review your words definition.
ArrayList Documentation: http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
Regards,
Bruno
Your code is a bit off for a dynamic array (Java has immutable arrays), so you need an ArrayList. Also, Java uses Capital Letters for class names (please follow the convention) -
// like this, changing wordClass to WordClass. Also, using the diamond operator
private ArrayList<WordClass> words = new ArrayList<>();
To access your WordClass fields you can use something like -
for (WordClass wc : words) {
if (wc.used) {
System.out.println(wc.wordValue + " = " + wc.val);
}
}
Note, you still need to create WordClass instances and place them into the words List.
Write wrapper classes for each value. e.g. What you call "getters".
Then call:
words[1].getWordValue() ==> None
Voila
I want a 2D Matrix with one line of strings and the other line with int's.
Is that possible?
Or do I have to save the int's as strings and later convert them to int's again?
Rather use an object.
class MyEntry {
String foo;
int number;
}
MyEntry[] array = new MyEntry[10];
But if you must, you can use two types - only through an Object supertype.
Object[][] arr = new Object[2][10];
arr[0][0] = "Foo";
arr[1][0] = new Integer(50);
No it is not possible . There can be only a single datatype for an array object. You can make a class having both the int and String as property and use it. Never use an Object[][] even if there is a temptation to do so, it is an evil workaround and hacks fail more than they succeeded . If Object was a sound technique then they wouldn't have introduced Generics for Collection !
You can create Objects 2D array and place there Strings and Integers, but I am not sure if it is good idea to have mixed types in arrays. You should probably describe your problem more so we could figure out better way.
Yes it is. If you declare as a Matrix of object then you can store string and Integer (not int), the difficulty will be after to retrieve them correctly :)
You can create an array of the type Object and store any non-primitive Object in there.
When you retrieve them, you'll need to make sure you check their class though.
if(objArray[0] instanceof String) {
// do string stuff
} else if(objArray[0] instanceof Integer) {
// do integer stuff
}
etc.
I think you're better off creating a new class that can store objects of the types that you want and just retrieve them using getters and setters. It's a lot safer and more stable.
You could do it if you do a 2D array of Object as in Object[][] myArray = new Object[x][y] where x and y are numbers.
All you would have to do is cast the Objects to their expected types before using them. Like (String) myArray[0][3] for example.
YOu should only do it this way if you know for certain what type the Object in a particular location will be.
However, it's generally not a good idea to do things this way. A better solution would be to define your own data structure class that has a String array and an int array as member variables. As in:
public class myData {
String[] theStringArray;
int[] theIntArray;
public myData(String[] sArraySize, int[] iArraySize) {
this.theStringArray = new String[sArraySize];
this.theIntArray = new int[iArraySize);
}
...
// Additional getters / setters etc...
...
}
Without getting bogged down with specifics, my code represents a library whereby each book is made up of a Set of pages containing a Set of Words.
I have created my own Set implementations:
class PageSet<E> extends HashSet<E>(){
public boolean set(int index, E e){....}
....
}
and
class WordSet<E> extends HashSet<E>(){
public boolean set(int index, E e){....}
....
}
I've got stuck when I try to create a Book in my main class:
Set<Set<Word>> dictionary = new PageSet<WordSet<Word>>();
Which results in a type conversion mismatch. However it will quite happily accept
Set<Set<Word>> dictionary = new PageSet<Set<Word>>();
Could someone please shed some light as to what I'm doing wrong when using a generic setup like this?
Basically, a PageSet<WordSet<Word>> is not a Set<Set<Word>>, because X<Subclass> is not a X<Superclass>.
If you had said
Set<WordSet<Word>> dictionary = new PageSet<WordSet<Word>>();
then that would have worked also.
It's either
Set<Set<Word>> dictionary = new PageSet<Set<Word>>();
or
Set<WordSet<Word>> dictionary = new PageSet<WordSet<Word>>();
Since although WordSet is a subclass of Set, a Set<WordSet> is not a subclass of Set<Set>.
In other words, generics are not covariant, which is different from things like arrays.
In any case, you should not extend collections unless you are trying to create new collection types. Since you cannot restrict the visibilities of superclass methods in a subclass, people will be able to write
WordSet<Word> words = ...;
words.clear();
You probably do not want to give clients that power. Instead, use aggregation instead of inheritance.
class Word {
private String text;
private PartOfSpeech part;
// Constructors, getters, setters, equals, hashCode are elided.
}
class Page {
private int pageNumber;
private Set<Word> contents = new HashSet<>();
public class Book {
private String title;
private List<Page> pages = new ArrayList<>();
}
Pages in a book are ordered linearly, which is why I used lists. I'm not sure why you used sets. But in any case, by encapsulating the collections inside the classes, you can provide client code exactly the interface you want them to use. The visibilities were chosen deliberately; this looks like a cluster of related classes, but you might want to change them.
I have a readData() function that reads files a returns a few different objects of parsed data. Right now, the return type of readData() is Object[]:
Object[] data = readData();
MyGenome genome = data[0];
Species[] breeds = data[1];
//etc
This feels awkward. Is there a better way to return this data? I don't want to have separate functions like readGenome() and readSpecies() because that would require iterating over the files twice. Also, I'd rather wrap up all the gathering of data in one function.
A similar issue: a function that returns a match of at least four characters between two strings:
public int[][] findMatch(String g0, String g1) { /* cool stuff */ }
//...
int[][] bounds = findMatch("ACOIICOCOCICOICA", "AOCCCCCCICCIIIIIOIAOCICOICOICA");
where bounds[0][0] is the left bound on the g0, bounds[0][1] is the right bound on g0, bounds[1][0] is the left bound on g1, etc. This also feels sort of awkward. It is difficult to code with the result without continuously looking up the keys.
Create a new Class:
class MyAnalysedGenome {
MyGenome genome;
Species[] species
...
}
and return that. You'll probably find you have other functionality that should go in there too. Perhaps the code that surrounds your getData() call.
How about using a strongly typed class to represent the complex return type of readData()?
public class Taxonomy
{
public MyGenome genome;
public Species[] breeds;
//etc
{
Taxonomy data = readData();
You can do the same thing for your search bounds problem
public class SearchBoundary
{
public int left;
public int right;
}
SearchBoundary resultBounds = findMatch(searchBounds);
For the first issue,couldn't you simply use an intermediate data representation ? I mean you could read your file once, which would give you the file content (that you could format the way you want), and then create two methods readGenome() and readSpecies() that would take this file content as a parameter.
You can create a class that have genome and species as fields.
...
class DataToBeRead {
MyGenome genome;
Species[] breeds;
}
...
DataToBeRead data = readData();
MyGenome genome = data.genome;
Species[] breeds = data.breeds;
You can make the class private if you do not think anybody else will used it or make it public if someone else will use it.
You can also make it static if you do not want to create a separate file for it.
Hope this helps.