Return of two components in JAVA - java

i have written the following method in JAVA:
protected List<Symbol> fields = new ArrayList<OCLFieldSymbol>(); (**)
public List<Symbol> getArgs(TypeArt kind) {
return (kind, fields);
}
I use Eclipse and it underlines "fields" in the return section with red. When I put the mouse to the red-underlined place, Exclipse makes the following suggestions:
Create field `fields` in type `TypeArt`
Create constant fields in type `TypeArt`
But I do not want to create such a field. It should return the "fields" from the first line (see (**)).
What can I do ? I am new in JAVA and learning it. So I hope someone can help me.
best regards

Java methods are limited to at most one return value, in this case a List<Symbol>. If you really need to have multiple values returned--and you usually don't--you will need to make a class to contain them.
In this case, you're already passing kind in as a parameter, so it doesn't make sense to try to return it; just return fields.

you could try something like this:
public List<Symbol> getArgs(TypeArt kind) {
List<Symbol> temp= new ArrayList<Symbol>();
for (Symbol field:fields){
//determine if field is the kind you want it to be
//if it is add it to temp using temp.add(field)
}
return temp;
}
If you want to return all the elements from fields that are of type kind you first need to create a new list using new List<Symbol>. Once the list is set up you then need to go though the list and determine which ones are the type you want. If they match the type you want you add them to your new list. when you are done looping you return the new list. In your method you told it that it will be returning a List<Symbol> that means that the return statement needs to be a list of symbols. (kind, fields) is not a List object.

Related

Do arraylist needs to be specified as return type in method after modification?

I would like to know what is the best practice to return 'updated' ArrayList?
For example, if I am adding in a new element, it seems that whether if I did or did not specify the return type (see the addNewA() and addNewB()), the ArrayList in my main() method will still be 'updated' nonetheless.
Should I or should I not specify the return type?
Currently in my client program, most of the methods, I have specified it as void (no return type) and while the overall program still does works as intended, thought I would like to get this clarified and make the necessary changes if necessary.
public class MyClient
{
public static ArrayList<Person> addNewA(ArrayList<Person> myArray)
{
Person jack = new Person("jack", 24);
myArray.add(jack);
return myArray;
}
public static void addNewB(ArrayList<Person> myArray)
{
Person ben= new Person("ben", 19);
myArray.add(ben);
}
public static void main(String[] args)
{
ArrayList<Person> personArray= new ArrayList();
addNewA(personArray); // will return me an array size of 1
addNewB(personArray); // will return me an array size of 2
}
}
In a case like this, you should not return the list and should make your method void.
Different languages have different conventions, but one of Java's is that methods that operate by modifying their arguments (or the object they're called on) should not return values. Returning a value implies to someone using your code that a different object is being returned, since otherwise there is no use in returning an object the caller already has1. A method that is void, on the other hand, couldn't possibly be returning a copied-and-extended list, so it's very clear that it's intended to operate by modifying the list that you give it in the first place.
(By the way, you should also just use List<Person>, and you should pay attention to the warning you get about using new ArrayList() instead of new ArrayList<>().)
1 There is a specific exception to this, called the fluent builder pattern, but it's not easily confused with general code like this.
In java (and most high level strict type languages) Objects are passed by reference and primitives passed by value.
When using the new keyword you create an object.
While primitives (like int, char, double ect) are passed by value (meaning that a copy of the value of the variable will be sent to the invoked function), Object types are passed by reference, meaning that the actual original object is passed to the function.
To sum up - since you are using object here (ArrayList), you don't need a return type since the original object is changing.

Java - Manual object validation against a white list

I'm trying to write a class to take a mega object, and ensure that only certain fields have been changed, normally you would annotate / add validation this way, but that is not an option in this case unfortunately, the only thing I can change is the one class I am working on, which will receive the very large (and very nested!) object that I'm supposed to somehow validate.
My initial thoughts was to make a 'list' of things that can be changed, then iterate over all properties in the object and check if anything has been updated that is not on the 'whitelist', I have the old version of the object, so I can check each field against the old one to confirm, but I'm not entirely sure how to do this, or if there is a better solution. I've never tried something like this before.
Any suggestions are appreciated. If there aren't any better solutions, how should I create the white list / iterate over all properties / nested properties of the mega object?
UPDATE:
Based on the suggestions, here is what I'm trying out, it still have a few problems though (Please note I'm just throwing things around, this is by no means my final class or good programming yet):
isTraversable works on collections, but I'm not sure how to get check custom classes, eg. a Person class, which would still need to be iterated through.
There are cyclic refs all over the place, not sure how to handle those either.
public class Test {
private Object obj1;
private Object obj2;
private List<String> whitelist;
public void validate(Object objectToTraverse,
Object objectToCompareTo,
List<String> whitelist){
this.obj1 = objectToTraverse;
this.obj2 = objectToCompareTo;
this.whitelist = whitelist;
traverseAndCompare(obj1, obj2);
}
private void traverseAndCompare(Object objectToTraverse,
Object objectToCompareTo){
try {
for (Field field : objectToTraverse.getClass()
.getDeclaredFields()) {
field.setAccessible(true);
Object fieldValue = field.get(objectToTraverse);
if (isTraversable(field)) {
traverseAndCompare(field.get(objectToTraverse),
field.get(objectToCompareTo));
} else {
getFieldValuesAndCompare(field, obj1, obj2);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean getFieldValuesAndCompare(Field field,
Object obj1,
Object obj2)
throws Exception{
Object value1 = field.get(obj1);
Object value2 = field.get(obj2);
return compare(value1, value2);
}
private boolean compare(Object value1,
Object value2){
return Objects.equals(value1, value2);
}
private boolean isTraversable(Field field){
// This should handle collections, but it does not work
// on custom classes, eg. Person class
if (Collection.class.isAssignableFrom(field.getType())) {
return true;
}
// Need to somehow figure out is this is a class with
// properties I can traverse, or something with a value,
// like String, Long, etc, hopefully
// without listing everything
return false;
}
}
Putting descriptive answer since object can not be shared due to legal reason.
You have couple of choices. Each with pro and con.
Reflection
You can maintain a list of fields not allowed to change with their full path. Like a.b.c. You can then write pure reflection code or use common utils like http://commons.apache.org/proper/commons-beanutils/ to get values (even deep in object tree) and compare.
It needs less code and less maintenance. But you need to know exact list of blacklist fields. Performance wise it will take little bit more time.
Simple plain code technique
Write your own comparator or method in java to go through all fields that can not change and decide. Need lot of code but very easy to maintain and performance wise best.

How to access a struct via an ArrayList in Java

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

How I return array of my class type object?

Reedited...
public EventData getEventDetails(String evtId, String Status) {
//do some data selection here.
return evData1;
}
public EventData[] getAdminAuthEvtDetails(String evtId, String Status) {
String eId=evtId;
String status=Status;
EventData[] evData=new EventData[2];
EventData[0] evData=getEventDetails(eId,"V");
EventData[1] evData=getEventDetails(eId,"M");
return evData;
}
EventData is my java data class. In there I set getters and setters. I want to call getEventDetails method two time one status as verified and other as modified for requested ID and set both evData into one array. In here there give a error couldn't get data into EventData[0] and EventData[1].Is there any error of calling my getEventDetails method?
Finally I got correct code.
EventData[] evData=new EventData[2];
evData[0]=getEventDetails(eId,"V");
evData[1]=getEventDetails(eId,"M");
return evData;
in both methods you must return an object rather than Type
in 1st method:
public EventData getEventDetails(String evtId, String Status) {
return new EventData(evtId, status);//don't know how is you constructor of EventData, but its just a smart guess. the idea is to create an object
}
and in 2nd method return eData;
I believe you need to update your getEventDetails method as well. EventData is a class however you need to return an instance of the class generally created by calling the constructor new EventData().
Otherwise, ay89 is correct that getAdmin... should return eData.
Conceptually, it's correct. You just have some syntax issues that others have mentioned (like returning a variable instead of a class).
Otherwise, some other things to note:
You'll want to probably use a lowercase "s" for "Status" since conventionally, variables shouldn't start with upper cases.
You probably dont need to redeclare the evtId to eid. You can just use the evtId (and the incorrectly cased Status) variable directly.
Personally, I like to perhaps call the getEventDetails(...) method something more like createEventDetails(...) since it's more indicative of the function of that method. "Get" always implies fetching instead of creating to me.
Just my 2c

Java ArrayList: Adding object using string name

This is a very straightforward task, but I feel I'm overlooking something. I have multiple objects that I'm trying to add to an ArrayList, and each of them has an identifying name in the form of a String. I need to be able to find (interact) with the objects in the ArrayList by calling the string name. So I tried this:
In my item class I have:
private String itemName;
public Item(String name)
{
itemName = name;
}
So I can give it a name to be used by the user.
Then in my class that interacts with the object, I create an ArrayList:
private ArrayList<Item> items = new ArrayList<Item>();
I add an object to the arrayList first by it's actual object name, but I need to be able to interact with it using it's String name, so I tried this:
public void removeItem(String itemName)
{
for (int i = 0; i < items.size(); i++)
{
if (items.get(i).toString() == itemName)
{
items.remove(i);
}
break;
}
}
But it's not removing the item. If all of this is confusing, in essence I'm trying to create an OBJECT that I can give a STRING name (like I did with the item above), then have the ability to add the OBJECT to an ArrayList, and then finally be able to remove, or get, or do something with the OBJECTS in the ArrayList by calling the STRING name. I know I need to iterate through the ArrayList, but I can't actually get the object.
Thanks for any help.
You are dong three mistakes here:
You are using items.get(i).toString() which will not give you itemName for your Item. It will just give you a string representation of your Item class, returned by Object class's toString method, if you don't override one. However, this might work, if you have overriden a toString method, and returned the itemName from that. But, that I don't see. And even if you have overriden that, I suggest you to have getter and setter for your itemName field, and use that to return the itemName.
You are comparing strings using == operator, which will not give you correct result. You should always compare the string using equals method.
So, your if statement should look like:
if (items.get(i).getName().equals(itemName))
3rd problem is, you are trying to modify the List that you are iterating upon. This will not work out, and may throw ConcurrentModificationException. You should use Iterator to remove elements from the List while iterating.
See for more details about those two problems, and how to solve them:
How do I compare strings in Java?
Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop
Further, you can consider overriding equals method in your class, and then you can directly compare your instances using equals method.
Now, having pointed out the some logical problems with your code, it's time to point out some design problems.
Given your requirement, it seems like you need to use a HashMap, rather than a List of some custom type storing your attribute. You can create a map like this:
Map<String, Integer> map = new HashMap<String, Integer>();
which will contain the mapping of itemName to respective Item, and then getting the Item for a particular itemName is as simple as map.get(itemName).
It sounds like you should be using a Map for this, for instance java.util.HashMap<String, Item>. The Map interface provides exactly those operations you're looking for, and it is also iterable.
add a getter to your object to get the name, like so:
public class Item {
private final String name; //once given cannot change
public Item(String name) {
this.name = name; //yhis.name to distinguish between 2 variabled both called "name"
}
public String getName() {
return name; //this.name not required as no other variable called "name" is in scope
}
}
then you could find your Item like this:
for (Item item : theList) {
if (item.getName.equals(requiredName)) {
//got you!
}
}
generally speaking, dont ever compare strings with ==. also, if you want to remove an item from a list youre iterating over you have to use the (older) iterator syntax:
Iterator<Item> iter = theList.iterator();
while (iter.hasNext()) {
Item item = iter.next();
if (item.getName.equals(requiredName)) {
//got you!
iter.remove();
break; //no need to go over the rest of the list
}
}
and lastly, if all you want is to look up items by their name a list is not your best collection since finding the item may require traversing the entire list. maps (hashmap specifically) will give you much better performance for this type of operation. you could use the name as the key
my guess is that you items.get(i).toString() does not do what you think it does. Why don't you use some thing like items.get(i).name or create getters or setters for name in Item object and retrieve name by items.get(i).getName()
There is this - the way you implemented the removeItem, you can also do it directly using
ArrayList.remove(item.itemName)- that's just before you get all stuck up with ConcurrentModificationException and reimplementing stuff that already exists - look at the library!! Read the documentation of ArrayList!
For clarification: in Java (and mostly really only in Java): == means comparison of references.
So:
String a = "A";
String b = new StringBuilder("A").toString();
if (a == b) // --> false
if (a.equals(b)) // --> true
You could also consider using org.apache.commons.lang.StringUtils.equals for that - which is safe regarding null pointers.
As others already pointed out - the toString-method will only work correctly if you implement it correctly (returning the name in your case). By original toString returns a class-name together with an ID. That's probably not what you want (simply try to print it out).

Categories