I have method that parses a list of String records into objects and returns List of objects. So my method signature is like this.
public List<ParsedObject> parse(String[] records);
But I also want to return, other metrics like number of string records that were not parsed successfully. Now I get confused, how to return this metric. One option would be to create another wrapper class that holds both list of parsed records and members to store these metrics.
But I face this situation very often and this way I would end up in creating many wrapper classes.
Not sure if I explained well. Any suggestions here?
Java does not support returning multiple values from a function, unfortunately. You can create a wrapper class, like you said. Another option is to pass in an array of integers or a "metrics" object or something like that and modify it inside Parse. Slightly better might be to have one or more instance variables (rather than method variables) to keep track of any sort of diagnostic information you need.
Your question has already been discussed (see this for example: Should Java method arguments be used to return multiple values? ). I personally think that you should either make two method calls, if the returned data is not related. If they are, then you should create a "wrapper" class as you call it. If they really are related data then they probably belong in the same class anyway.
I don't personally favor modifying passed in objects because to me it is a side effect, and it is not clear to see what the method really does.
Another way to think of it is to use the factory pattern (see http://en.wikipedia.org/wiki/Factory_method_pattern) if the object you are building is complex.
Create a ParseResult object. You could include the List, number of records parsed, errors, etc. Make it generic enough so that it could be returned from different methods. You could even make it a base class and return classes that extend from it. Just keeping thinking in terms of objects.
You can return a complex object containing the list and all the information you need.
Maybe this could help http://www.yoda.arachsys.com/java/parameters.html
I was going to suggest to you some kind of 'c++ pair' type, but then I found this: What is the equivalent of the C++ Pair<L,R> in Java?
A wrapper class is the standard way of returning more information from a function. Another alternative would be to pass another parameter by reference and modify it in your function, thus effectively returning new information to the caller. For example, in your case you would pass an empty list and add all the parsed elements in that list. The return type could be a metric or an error code. Thus the caller will have both pieces of information.
This is a very common problem for many people who develop using Java. In other languages, such as Scala, one can create tuples, which are anonymous objects which can hold multiple values, and use them as arguments or return values.
Related
Ok - the title doesn't make much sense. I apologize in advance - I'm relatively new to some Java concepts:
I have a class, which looks a little like this (simplified):
public class SomeContainer {
T someEntity;
Map<String, Map<String, List<SomeOtherClass>>>> someCrazyMapping;
}
I have a variable of type SomeContainer, let's call it container1.
I want to make container2, which is essentially an exact copy of container1, but I'm going to make some modifications to container2's "crazy mapping".
What I tried doing is creating a "copy" of container1 as follows:
SomeContainer container2 = new SomeContainer(container1.getSomeEntity(), container1.getSomeCrazyMapping())
The constructor is an #AllArgsConstructor - and just copies the values as this.someEntity = someEntity (etc.)
If I put entries into the "crazyMapping" in container2, does container1 get affected at all? I am running it to check how it behaves, but if someone could explain how this works, it would be greatly appreciated.
Note that this answer was prior to your edit regarding the nature of the constructor, so some of this stuff may be extraneous, but the concepts still hold, so there's not much for me to change here except to add that your situation is the 4th bullet point in the first list below, so the possibility of modifying container1 via changes to container2 does exist, and you'll want to do a shallow or deep copy of that map rather than storing a reference to it.
Basically, "what happens to container1" is exactly what you tell your code to do to container1. Nothing tricky will happen behind the scenes.
So, there's no way to give a definitive answer from the information given, but from this line:
SomeContainer container2 = new SomeContainer(container1.getSomeEntity(),
container1.getSomeCrazyMapping());
The best we can tell you from what you've shown is that container1 will not be "modified" (depending on what you consider "modified") as long as:
Your implementation of getSomeEntity() does not modify container1, and
Your implementation of getSomeCrazyMapping() does not modify container1, and
Your implementation of that constructor does not modify the parameters you pass in (e.g. by calling clear() on the map you pass it or something) in a way that causes container1 to be modified.
Your implementation of that constructor does not create situations where you could modify container1 via container2 later, e.g. you return the map directly in getSomeCrazyMapping(), store a reference to it in container2, then modify it via that reference.
I use the term "modified" loosely, since it really depends on your situation what you consider to be "modified", but no, nothing's going to just randomly happen, you have to analyze your code to see if you are explicitly modifying anything.
So to help you maintain careful control over things you have a few tools at your disposal. Here are some examples, and it's left as an exercise to you to figure out how you can use these effectively:
Most maps have shallow "copy constructors", e.g. HashMap. References to the same key and value objects will be stored in the copy but it will at least be a different map.
You've got e.g. Object#clone that you could implement on your containers, key and value objects, whatever. Note that some maps implement Cloneable as well, see for example HashMap#clone.
You've got e.g. Collections#unmodifiableMap that you could use to wrap the return value of getSomeCrazyMapping() if you want to programmatically ensure that nobody is adding/removing values to the map returned by that method.
Here are some techniques for deep copying generic Maps, if you are sticking to generic Map interfaces, which can be tricky.
Also don't forget you can do your copy on a "higher" level. For example if your containers have their own "add/insert" operations and their own "get"/iterator operations you can just not do the under-the-hood stuff and use your high level methods instead, which can greatly simplify your code (totally made up example), and remove dependence on the actual implementation details of your containers:
public SomeContainer (SomeContainer other) {
for (ExampleEntry entry : other.getEntries())
this.addEntry(entry);
}
Fwiw, this is the approach I'd probably take myself if my container implementations were getting complicated.
Just a small set of things you have to work with here. Documentation is also your friend, clearly document your invariants and assumptions like "Modifying the map returned by this method will modify this container" or "This constructor creates deep copies of its parameters", etc. Then stick to those in your implementations (and test!).
Declaring an object like this does not affect the initial object. If you declared the object like
SomeContainer container2 = container1;
then when you modify container2 it would modify container1 as well.
I need a solution to the following problem. Suppose I have different fields in a class. Each of different type, some may be basic types such as Integers, some may be complex object type fields. I need to find a way to compare those fields after exit and restart of the app. By I am limited to dumping the values to file and comparing those. How can I put something on file and compare them so that I can determine whether they have changed or not. I do not need the values. Will getHashCode() help?
If I understand your question, you would like to compare content in a file after exit and before restart. One way would be to use a message digest. As in calculating the SHA1 of the contents and comparing that before restart.
It sounds like Java object serialization might do the trick for you. With serialization, you can write any object to a file, and later read it in again and reconstruct the original object. If you then have an isEqual() method on the object, you can use that to simply check whether the object is the same.
EDIT: reread the question. If you want to compare the file contents, then serialization is not particular useful, as there are bound to be small differences between the two files.
I guess hashCode() will help only if it's implemented in such a way that will return the same result for two objects if the objects have the same values. Of course, for non-primitive fields you'll have to decide what does "same value" mean, and you would be probably required to implement hashCode() for the types of those fields as well.
If you can't/don't want to implement hashCode() maybe JSON could help. I suggest using a library like Google's Gson to render a string representation of your object which you can then dump to file. If the way in which the object (or any of its members) is converted to string does not suit your needs you can specify the conversion with a JsonSerializer.
String strRep = new Gson().toJson(myObject);
I Know I can use Generics while defining the ArrayList to do that. But here the case is different.
I have a ArrayList, which when defined accepts any type of Objects. Once the user inserts the first Object, I need to use Class Reference to Find the Class of that Object and then have to ensure that only Objects of that Class are inserted in the ArrayList.
Example:
ArrayList arrayList = new ArrayList();
Now lets say the User enters an object b, of Class B in the arrayList, then from now onwards, I must only allow objects of type B to be added to the arrayList.
I know that I can find the class of the Object inserted using:
arrayList.get(0).getClass();
But what after it? How will I use the Class type I just found?
Since this is an interview question I won't give you a complete answer, but you might want to take a look at the Class.isAssignableFrom method.
You cannot use generics for this, you need to implement runtime checks.
One way would be to subclass ArrayList and implement the various add methods in a way that checks the type of what is being added.
get(0).getClass().cast(newObject);
// will throw a ClassCastException if it does not match
hmm .. you can do the comparison on the class names - not elegant but should do your work ..
get(0).getClass().getName().equals(classname for the pushed value)
I see some design issues in the code rather how to solve this issue. The flow of the code should determine what the code is doing so that it does not send the collection to a method which can put any arbitrary objects (by checking or not) in it.
I would advise to revisit the design.
For example, if someone is trying to put a soccer ball into the collection and then the collection should be passed into a method where it can deal with a soccer ball. They can use a common code or command pattern for handling any ball or specific behavior for soccer ball and so on.
The same is true if the code wants to put a base ball into a collection, it better knows what its going to do next.
It is a design issue... It is not a code issue.
Say you are adding x number of objects to a collection, and after or before adding them to a collection you are modifying the objects attributes. When would you add the element to the collection before or after the object has been modified.
Option A)
public static void addToCollection(List<MyObject> objects) {
MyObject newObject = new MyObject();
objects.add(newObject);
newObject.setMyAttr("ok");
}
Option B)
public static void addToCollection(List<MyObject> objects) {
MyObject newObject = new MyObject();
newObject.setMyAttr("ok");
objects.add(newObject);
}
To be on the safe side, you should modify before adding, unless there is a specific reason you cannot do this, and you know the collection can handle the modification. The example can reasonably be assumed to be safe, since the general List contract does not depend upon object attributes - but that says nothing about specific implementations, which may have additional behavior that depends upon the object's value.
TreeSet, and Maps in general do no tolerate modifying objects after they have been inserted, because the structure of the collection is dependent upon the attributes of the object. For trees, any attributes used by the comparator cannot be changed once the item has been added. For maps, it's the hashCode that must remain constant.
So, in general, modify first, and then add. This becomes even more important with concurrent collections, since adding first can lead to other collection users seeing an object before it been assigned it's final state.
The example you provided won't have any issues because you're using a List collection which doesn't care about the Object contents.
If you were using something like TreeMap which internally sorts the contents of the Object keys it stores it could cause the Collection to get into an unexpected state. Again this depends on if the equals method uses the attribute you're changing to compare.
The safest way is to modify the object before placing it into the collection.
One of the good design rules to follow, is not to expose half-constructed object to a 3rd party subsystem.
So, according to this rule, initialize your object to the best of your abilities and then add it to the list.
If objects is an ArrayList then the net result is probably the same, however imaging if objects is a special flavor of List that fires some kind of notification event every time a new object is added to it, then the order will matter greatly.
In my opinion its depend of the settted attribure and tyle of collection, if the collection is a Set and the attribute have infulance on the method equal or hascode then definitely i will set this property before this refer also to sorterd list etc. in other cases this is irrelevant. But for this exapmle where object is created i will first set the atributes than add to collection because the code is better organized.
I think either way it's the same, personally I like B, :)
It really does boil down to what the situation requires. Functionally there's no difference.
One thing you should be careful with, is being sure you have the correct handle to the object you want to modify.
Certainly in this instance, modifying the object is part of the "create the object" thought, and so should be grouped with the constructor as such. After you "create the object" you "add it to the collection". Thus, I would do B, and maybe even add a blank line after the modification to give more emphasis on the two separate thoughts.
I just want to know for what java.util.Collections.checkedList() is actually used.
I have some code that I know is returning me a List<String> but it's being passed through a chain of messaging calls and returned to me as a java.io.Serializable. Is that checkedList call good for me to turn my Serializable into a List<String>? I know I can cast it to a java.util.List, but I'd rather not have to check each element and I'm not comfortable with assuming each element is a String.
It is used in part as a debugging tool to find where code inserts a class of the wrong type, in case you see that happening, but can't figure out where.
You could use it as part of a public API that provides a collection and you want to ensure the collection doesn't get anything in it of the wrong type (if for example the client erases the generics).
The way you could use it in your case is:
Collections.checkedList(
new ArrayList<String>(uncertainList.size()), String.class)
.addAll(uncertainList);
If that doesn't throw an exception, then you know you are good. That isn't exactly a performance optimized piece of code, but if the list contents are reasonably small, it should be fine.
Not quite:
Collections.checkedList will only decorate the list to prevent any future inserts with objects of the wrong class, it won't check all the elements that are already in the list.
However, you could make a new checkedList, and then call addAll and pass in the list you are unsure about - rather than writing the loop yourself.
A discussion of what checkedList could be used for is available in the documentation for checkedCollection. The reasons given are:
as a debugging aid (if someone has used an unchecked cast)
to ensure safety when passing a collection to be populated by third-party code.
You could use the following from google collections to check that the list does only contain strings:
Iterables.all(list, Predicates.instanceOf(String.class))