3

I'm fairly new in Java, and I'm making a structure for wrapping this kind of data:

Object:
    name:'Obj1'
    otherAttr:'...'
Object:
    name:'Obj2'
    otherAttr:'...'
Object:
    ...

I know that I can make my custom 'Object' class*, but for using builtin java structures I use List<Map<String, String>>. So, for setting new one:

List<Map<String, String>> objects = new ArrayList<Map<String, String>>();
foreach(databaseRow){
    Map<String, String> newObject = new HashMap<String, String>();
    newObject.put('name', '...');
    newObject.put('otherAttr', '...');
    objects.add(newObject);
}

I have two questions:

1- If the initializations of the structures (as an ArrayList and as an HashMap) are the best choises between the huge amount of Java structures.

2- If there is a builtin structure that doesen't implies all those initializations (for the List and for each Map).

Thank you!

(*)CLARIFICATION: I use plenty of structures similar of that in my code, and I would avoid to make a lot of custom classes. But if it's the best way, let's do it!

T30
  • 11,422
  • 7
  • 53
  • 57
  • 5
    If you want make it clean, you should really create your own custom class. Is there any specific reason why you would need to avoid that? – Haroldo_OK Feb 26 '15 at 11:25
  • 1
    I agree with @Haroldo_OK but just to make that more clear: Your own class will be *composed* out of data structures from the Java Collections Framework. They are just using them and giving your types a semantically more meaningful interface. – 5gon12eder Feb 26 '15 at 11:26
  • hmm just a hint, why won't you use the Map Structure by its own rather than creating an list on top of it – nafas Feb 26 '15 at 11:27
  • @nafas Because after that, I want to iterate through the List of Objects, and make an action for everyone. I can't figure out how to make it using only the Map. – T30 Feb 26 '15 at 11:31
  • @T30 But why a map and not a custom class where you can hide away the implementation details, the whole point of encapsulation. – JamesB Feb 26 '15 at 11:32
  • Map also has iterator, you can simply iterate through them – nafas Feb 26 '15 at 11:32
  • A single `Map` is not the solution. It won't allow you to put two `"name"` keys with different values in it and you won't be able to tell to what object `"someAttr"` refers to, once added to the collection. – 5gon12eder Feb 26 '15 at 11:32
  • @nafas: 5gon12eder replied quickly than me! The problem is that I use plenty of structures similar of that in my code, and I would avoid to make plenty of classes. But if it's the best way, let's do it! – T30 Feb 26 '15 at 11:35
  • @T30 yeah my bad mate, there was a misunderstanding from my side while reading the question. But out of curiosity, you may consider JsonArray for your structure. – nafas Feb 26 '15 at 11:38
  • @T30 Does each `Object` contain only the 2 properties "name" and "otherAttribute"? Or are there eventually more than 2 properties for an object? – SME_Dev Feb 26 '15 at 11:39
  • @SME_Dev, I need other implementations that use few more attributes. I will make an extensible thing :) – T30 Feb 26 '15 at 11:45

6 Answers6

2

If each of your objects has only these two attributes (name and otherAttr), you could create a class with fields instead of using Map:

public class Data {
    private final String name;
    private final String otherAttr;
    // constructor, getters
}

It may be useful to do so even if you have more attributes, because it gives you compile-time safety - you will never misspell a key. You can also have fields of different types, not just Strings that you would have to parse.

To make your code more meaningful you can also extend existing data structures, e.g.:

public class Data extends HashMap<String, String> {
    // extra convenience constructors
}

public class DataList extends ArrayList<Data> {
    // extra convenience constructors
}

In regards to your question what collections to use, it really depends on what you need. ArrayList is usually a good choice (or thread-safe Vector), unless you frequently modify the beginning of the list in which case LinkedList would be recommended. HashMap has very good performance, but if you need sorted data you could use TreeMap instead. If you need to maintain order of insertion LinkedHashMap will be the best.

Jaroslaw Pawlak
  • 5,538
  • 7
  • 30
  • 57
2

If the structure may vary, yes, it is the correct approach.

If each name is unique, you may use a Map<String,String>.

If the structure is always the same (pairs of name and otherAttr), you may use a POJO (plain old java object), which is a fancy name for an object with getters and setters:

 public class MyData {
    private String name;
    private String otherAttr;
    public String getName() {return name;}
    public void setName(String name) {this.name=name;}
    public String getOtherAttr() {return otherAttr;}
    public void setOtherAttr(String otherAttr) {this.otherAttr=otherAttr;}
 }

Then you store them in a List<MyData>.

You may provide a constructor for MyData, setting the values of name and otherAttr

 MyData(String name, String otherAttr) {
    this.name=name;
    this.otherAttr=otherAttr
 }
Community
  • 1
  • 1
Javier
  • 12,100
  • 5
  • 46
  • 57
  • 1
    A `POJO` is not the same as a `Java Bean`. The latter has getters/setters, while the former (a "plain old java object") may simply use public fields. – Aleksandr Dubinsky Feb 26 '15 at 11:38
2

Without questioning the essence of what you are doing, I will answer your question directly by saying that you are likely using the optimal data structures in the correct way.

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
1

you could make your own class an have a List of this objects.

List<myClass> objects = new ArrayList<myClass>();

konstantin
  • 126
  • 5
1

1- If the initializations of the structures (as an ArrayList and as an HashMap) are the best choises between the huge amount of Java structures.

No, write your own custom class(es) to hold the data. The whole point of encapsulation is to hide away the implementation details.

2- If there is a builtin structure that doesen't implies all those initializations (for the List and for each Map).

If you write your own class, your constructors for the class can handle the initialisation. That is what constructors are for.

JamesB
  • 7,774
  • 2
  • 22
  • 21
  • 1
    Semantic nitpicking: You are using `` for your own words and inline text for block quotes… – 5gon12eder Feb 26 '15 at 11:35
  • @5gon12eder is the way I have formatted my answer really an issue? – JamesB Feb 26 '15 at 11:36
  • 3
    If you have a good reason to do it this way, then go for it. But in general, semantically correct markup is important, especially to allow changes of the layout in the future or to support other devices than the monitor you are probably using. Coincidentally, using structures that work but convey the wrong semantics is just what this thread is about (and your answer is correctly arguing against). ;-) – 5gon12eder Feb 26 '15 at 11:44
1

This is correct, but if you want a cleaner approach why don't you create

public Class MyData{
   private String name;
   private String attr;  //in case you need multiple attributes, make this as list 
   //setters and getters
}

And then do

List<MyData> objects = new ArrayList<MyData>();
shikjohari
  • 2,278
  • 11
  • 23