Return an Object in Java - java

I've been struggling to work out how to return an object.
I have the following array of objects.
ArrayList<Object> favourites;
I want to find an object in the array based on it's "description" property.
public Item finditem(String description) {
for (Object x : favourites) {
if(description.equals(x.getDescription())) {
return Object x;
else {
return null;
Can someone please show me how I would write this code. Thanks.

Use generics:
ArrayList<Item> favourites;
public Item finditem(String description) {
for (Item x : favourites)
if(description.equals(x.getDescription()))
return x;
return null;
}
Or if you really do want to have an array of Objects, the return type of the method must be Object:
public Object findItem(String description)
but it really looks like you want favourites to be an arraylist of Items!

You can't call getDescription on a generic Object.
You want your ArrayList to be composed of a specific type of Object, that has the property description.
Since you have your class Item:
public class Item {
private String description;
public String getDescription(){
return description;
}
... other methods here
}
Now you can create an ArrayList of this type, such as:
List<Item> myList = new ArrayList<Item>();
And iterate over it the same way you're doing... almost.
Your iteration code is broken, since you'll always just check the first element, and return null if it's not what you're looking for, what you want is something like:
for (Item x : favourites) {
if(description.equals(x.getDescription())) {
return x;
return null;
Notice that this way you'll iterate over the entire list, and only if you reach the end of the cycle will you return null.

ArrayList<Item> or change return type to Object.

Related

check an object for a property value java

I'm looking for a way to loop through the properties of each object of a list of objects and check if the value of a specific property matches another value I already have. For my case, both values are strings, but I would like to know how to check for any type of value.
Iterating through the list is simple, I am confused how to check the properties though. What would be the best way to do this?
The objects are created through this constructor:
public Undroppable(Player nameOfPlayer, ArrayList<ItemStack> items1){
Player pl = nameOfPlayer;
ArrayList<ItemStack> storedHits = items1;
};
ItemStack is a type that was created in the api I am working with. items1 is an arraylist of itemstacks.
The constructor is used in the class like this:
storedDeaths.add(new Undroppable(p, hits));
storedDeaths is a list for the objects created. p is a player, another type in the api I'm using. Hits is the arraylist of itemstacks I was talking about.
I can loop throught the list of objects to access an object, but I don't know how to loop through each objects to check the properties.
Consider this:
interface PropertyProvider<E> {
public E getValue();
public void setValue(E value);
}
class Container implements PropertyProvider<String> {
private String value;
#Override
public String getValue() {
return value;
}
#Override
public void setValue(String value) {
this.value = value;
}
}
Then use this method to check whether one of the properties contained in the ValueProviders matches a value:
public static <E> boolean containsNestedProperty(Collection<PropertyProvider<E>> coll, E value) {
boolean contains = false;
for (PropertyProvider<E> provider : coll) {
E item = provider.getValue();
if (item != null && item.equals(value)) {
contains = true;
break;
}
}
return contains;
}
Just access your property in the loop and check if it is equal to what you want to match.
List<YourObject> list = new ArrayList<YourObject>();
String stringToMatch = "match"
for(int i; i<list.size(); i++){
if(list.get(i).getStringProperty().equals(stringToMatch){
//do something
}
}
Edit:
your class isn't set up correctly.You arent doing anything in the constructor.
Class variables need to be declared as such:
public class Undroppable{
private Player player; //this is important
private List<ItemStack> items1; //you must declare these
public Undroppable(Player nameOfPlayer, ArrayList<ItemStack> items1){
this.player = nameOfPlayer;
this.items1 = items1;
}
public Player getPlayer(){ return this.player; } // now you can access this way
public List<ItemStack> getItems1{return this.items1}

Create an ArrayList with multiple object types?

How do I create an ArrayList with integer and string input types? If I create one as:
List<Integer> sections = new ArrayList <Integer>();
that will be an Integer type ArrayList.
If I create one as:
List<String> sections = new ArrayList <String>();
that will be of String type.
How can I create an ArrayList which can take both integer and string input types?
Thank you.
You can make it like :
List<Object> sections = new ArrayList <Object>();
(Recommended) Another possible solution would be to make a custom model class with two parameters one Integer and other String. Then using an ArrayList of that object.
(1)
ArrayList<Object> list = new ArrayList <>();`
list.add("ddd");
list.add(2);
list.add(11122.33);
System.out.println(list);
(2)
ArrayList arraylist = new ArrayList();
arraylist.add(5);
arraylist.add("saman");
arraylist.add(4.3);
System.out.println(arraylist);
You can use Object for storing any type of value for e.g. int, float, String, class objects, or any other java objects, since it is the root of all the class. For e.g.
Declaring a class
class Person {
public int personId;
public String personName;
public int getPersonId() {
return personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}}
main function code, which creates the new person object, int, float, and string type, and then is added to the List, and iterated using for loop. Each object is identified, and then the value is printed.
Person p = new Person();
p.setPersonId(1);
p.setPersonName("Tom");
List<Object> lstObject = new ArrayList<Object>();
lstObject.add(1232);
lstObject.add("String");
lstObject.add(122.212f);
lstObject.add(p);
for (Object obj : lstObject) {
if (obj.getClass() == String.class) {
System.out.println("I found a string :- " + obj);
}
if (obj.getClass() == Integer.class) {
System.out.println("I found an int :- " + obj);
}
if (obj.getClass() == Float.class) {
System.out.println("I found a float :- " + obj);
}
if (obj.getClass() == Person.class) {
Person person = (Person) obj;
System.out.println("I found a person object");
System.out.println("Person Id :- " + person.getPersonId());
System.out.println("Person Name :- " + person.getPersonName());
}
}
You can find more information on the object class on this link Object in java
List<Object> list = new ArrayList<>();
list.add(1);
list.add("1");
As the return type of ArrayList is object, you can add any type of data to ArrayList but it is not a good practice to use ArrayList because there is unnecessary boxing and unboxing.
You could create a List<Object>, but you really don't want to do this. Mixed lists that abstract to Object are not very useful and are a potential source of bugs. In fact the fact that your code requires such a construct gives your code a bad code smell and suggests that its design may be off. Consider redesigning your program so you aren't forced to collect oranges with orangutans.
Instead -- do what G V recommends and I was about to recommend, create a custom class that holds both int and String and create an ArrayList of it. 1+ to his answer!
Create your own class which stores the string and integer, and then make a list of these objects.
class Stuff {
private String label;
private Integer value;
// Constructor
public void Stuff(String label, Integer value) {
if (label == null || value == null) {
throw NullPointerException();
}
this.label = label;
this.value = value;
}
// getters
public String getLabel() {
return this.label;
}
public Integer getValue() {
return this.value;
}
}
Then in your code:
private List<Stuff> items = new ArrayList<Stuff>();
items.add(new Stuff(label, value));
for (Stuff item: items) {
doSomething(item.getLabel()); // returns String
doSomething(item.getValue()); // returns Integer
}
It depends on the use case. Can you, please, describe it more?
If you want to be able to add both at one time, than you can do the which is nicely described by #Sanket Parikh. Put Integer and String into a new class and use that.
If you want to add the list either a String or an int, but only one of these at a time, then sure it is the List<Object>
which looks good but only for first sight! This is not a good pattern. You'll have to check what type of object you have each time you get an object from your list. Also This type of list can contain any other types as well.. So no, not a nice solution. Although maybe for a beginner it can be used. If you choose this, i would recommend to check what is "instanceof" in Java.
I would strongly advise to reconsider your needs and think about maybe your real nead is to encapsulate Integers to a List<Integer> and Strings to a separate List<String>
Can i tell you a metaphor for what you want to do now? I would say you want to make a List wich can contain coffee beans and coffee shops. These to type of objects are totally different! Why are these put onto the same shelf? :)
Or do you have maybe data which can be a word or a number? Yepp! This would make sense, both of them is data! Then try to use one object for that which contains the data as String and if needed, can be translated to integer value.
public class MyDataObj {
String info;
boolean isNumeric;
public MyDataObj(String info){
setInfo(info);
}
public MyDataObj(Integer info){
setInfo(info);
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
this.isNumeric = false;
}
public void setInfo(Integer info) {
this.info = Integer.toString(info);
this.isNumeric = true;
}
public boolean isNumeric() {
return isNumeric;
}
}
This way you can use List<MyDataObj> for your needs. Again, this depends on your needs! :)
Some edition: What about using inharitance? This is better then then List<Object> solution, because you can not have other types in the list then Strings or Integers:
Interface:
public interface IMyDataObj {
public String getInfo();
}
For String:
public class MyStringDataObj implements IMyDataObj {
final String info;
public MyStringDataObj(String info){
this.info = info;
}
#Override
public String getInfo() {
return info;
}
}
For Integer:
public class MyIntegerDataObj implements IMyDataObj {
final Integer info;
public MyIntegerDataObj(Integer info) {
this.info = info;
}
#Override
public String getInfo() {
return Integer.toString(info);
}
}
Finally the list will be: List<IMyDataObj>
You don't know the type is Integer or String then you no need Generic. Go With old style.
List list= new ArrayList ();
list.add(1);
list.add("myname");
for(Object o = list){
}
You can always create an ArrayList of Objects. But it will not be very useful to you. Suppose you have created the Arraylist like this:
List<Object> myList = new ArrayList<Object>();
and add objects to this list like this:
myList.add(new Integer("5"));
myList.add("object");
myList.add(new Object());
You won't face any problem while adding and retrieving the object but it won't be very useful.
You have to remember at what location each type of object is it in order to use it. In this case after retrieving, all you can do is calling the methods of Object on them.
You can just add objects of diffefent "Types" to an instance of ArrayList. No need create an ArrayList. Have a look at the below example,
You will get below output:
Beginning....
Contents of array: [String, 1]
Size of the list: 2
This is not an Integer String
This is an Integer 1
package com.viswa.examples.programs;
import java.util.ArrayList;
import java.util.Arrays;
public class VarArrayListDemo {
#SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
System.out.println(" Beginning....");
ArrayList varTypeArray = new ArrayList();
varTypeArray.add("String");
varTypeArray.add(1); //Stored as Integer
System.out.println(" Contents of array: " + varTypeArray + "\n Size of the list: " + varTypeArray.size());
Arrays.stream(varTypeArray.toArray()).forEach(VarArrayListDemo::checkType);
}
private static <T> void checkType(T t) {
if (Integer.class.isInstance(t)) {
System.out.println(" This is an Integer " + t);
} else {
System.out.println(" This is not an Integer" + t);
}
}
}
Just use Entry (as in java.util.Map.Entry) as the list type, and populate it using (java.util.AbstractMap’s) SimpleImmutableEntry:
List<Entry<Integer, String>> sections = new ArrayList<>();
sections.add(new SimpleImmutableEntry<>(anInteger, orString)):
For me this method works perfectly fine in jdk 16
import java.util.ArrayList;
public class Array {
public static void main(String[] args) {
ArrayList arrayList= new ArrayList();
arrayList.add("alien");
arrayList.add(1);
arrayList.add(0,'b');
System.out.println(arrayList);
System.out.println((arrayList.get(0)) instanceof Integer);
}
}
Output
[b, alien, 1]
false
User Defined Class Array List Example
import java.util.*;
public class UserDefinedClassInArrayList {
public static void main(String[] args) {
//Creating user defined class objects
Student s1=new Student(1,"AAA",13);
Student s2=new Student(2,"BBB",14);
Student s3=new Student(3,"CCC",15);
ArrayList<Student> al=new ArrayList<Student>();
al.add(s1);
al.add(s2);
al.add(s3);
Iterator itr=al.iterator();
//traverse elements of ArrayList object
while(itr.hasNext()){
Student st=(Student)itr.next();
System.out.println(st.rollno+" "+st.name+" "+st.age);
}
}
}
class Student{
int rollno;
String name;
int age;
Student(int rollno,String name,int age){
this.rollno=rollno;
this.name=name;
this.age=age;
}
}
Program Output:
1 AAA 13
2 BBB 14
3 CCC 15

Hibernate queries call toString() method

I have a list of names: List<Name>, Name has two methods:
toString() returns "Name: Tom"
getName() returns "Tom"
To query the database for persons with certain names, I'd do
// Query a single database entry
Query query = em.createQuery("FROM person WHERE name = :name");
query.setParameter("name", names.get(0).getName());
When I want to query multiple entries (using WHERE ... IN (...) I'd have to do this:
// Convert the list of name instances to a list of strings
List<String> nameStrings = new ArrayList<String>(names.size());
for (Name name : names) {
nameStrings.add(name.getName());
}
// Query multiple database entries
Query query = em.createQuery("FROM person WHERE name in (:name)");
query.setParameter("name", nameStrings); // JPA
query.setParameterList("name", nameStrings); // Hibernate
Do I have to build a second list? I'd rather do this:
// Query a single database entry
Query query = em.createQuery("FROM person WHERE name = :name");
query.setParameter("name", names.get(0));
and
// Query for multiple database entries
Query query = em.createQuery("FROM person WHERE name in (:name)");
query.setParameter("name", names); // JPA
query.setParameterList("name", names); // Hibernate
Short answer is yes, you need to build the second list. You need to provide a List of Strings (or rather a Collection), a List<Name> will never match this. I'd recommend making some kind of utility method that takes a List<Name> and return a List<String> of the names.
public static List<String> toNameStrings(List<Name> names) {
List<String> list = new ArrayList<String>(names.size());
for (Name name : names) {
list.add(name.getName());
}
return list;
}
I haven't been able to test the following, and I'm not sure I want to recommend it in any way, but I think you could make a List implementation that would return different object types depending on the state it's in. Using this you'd be able to do something like list.setStringMode(false) to use it as a List<Name> (though Generics are going out the window at this stage, they'll all be returned as Object), then list.setStringMode(true), to use it as a List<String>. It would look something like the following:
public class NameAndStringList extends ArrayList<Object> implements List<Object>
{
private boolean stringMode = false;
#Override
public boolean add(Object object)
{
return super.add(toName(object));
}
// Do the same for add(index, element)
// Do the same for set(index, element)
// Do the same for remove(object)
#Override
public boolean addAll(Collection<? extends Object> collection)
{
final List<Name> convertedCollection = new ArrayList<Name>();
for (Object object : collection)
{
convertedCollection.add(toName(object));
}
return super.addAll(convertedCollection);
}
// Do the same for addAll(index, collection)
// Do the same for removeAll(index, collection)
// Do the same for retainAll(index, collection)
#Override
public boolean contains(Object o)
{
return super.contains(toName(o));
}
// Do the same for containsAll(collection)
// Do the same for indexOf(object)
// Implement Iterator that checks the stringMode variable before returning value.
// Override all iterator methods to retrieve custom Iterator implementation.
// Override subList(fromIndex, toIndex) to make subList be an instance of NameAndStringList as well.
#Override
public Object get(int index)
{
if (stringMode)
{
return ((Name) super.get(index)).getName();
}
return super.get(index);
}
// Implement setStringMode(boolean)
protected Object toNameString(Object object)
{
if (object instanceof Name)
{
// Convert to String here
}
return object;
}
protected Name toName(Object object)
{
if (object instanceof String)
{
// Convert to Name here.
}
return object;
}
}
Note that this relies on you being able to convert a String to a Name as well as vice-versa, but you could always get rid of that bit if you know you'll always populate it yourself using Name instances. The general idea here is that the List stores Name instances, but is free to return String instances since it's a List<Object>. Again, I'm not sure I'd recommend this approach, but it should meet your requirements, or at least as close as I can get atm.

Write Java Comparator

I have created a Vector object to store data in Table object as Vector<Table>. Vector<Table> contains components as below.
[Vector<Record> records, String tableName, String keyColumnName, int recordCount, int columnCount]
I need to sort tableName in above Vector to my own order and return Vector<Table> with sorted tableNames for other processes.
I have wrote method as below.
private Vector<Table> orderTables(Vector<Table> loadTables) {
List<String> tableNames = new ArrayList<String>();
for (Table table : loadTables) {
String tblName = table.getTableName();
tableNames.add(tblName);
}
Collections.sort(tableNames, new MyComparable());
return null;
}
But I have no idea about how to write Comparator to this. My own sort order is stored in .properties file. I can read it and get value. But I have no idea about how to compare it.
How could I do it?
Before clarification
You need to write a Comparator for Table objects that delegates to the tableName's comparator:
new Comparator<Table>() {
#Override public int compare(Table one, Table two) {
return one.getTableName().compareTo(two.getTableName());
}
}
Note that this will consider Tables that have the same name to be equal. This can mess things up if you put these tables in a HashMap or HashSet. To avoid this, you can detect this case and return one.hashCode() - two.hashCode() if the table names are the same.
Guava's ComparisonChain is a convenient way to write such multi-stage comparisons:
new Comparator<Table>() {
#Override public int compare(Table one, Table two) {
return ComparisonChain.start()
.compare(one.getTableName(), two.getTableName())
.compare(one.hashCode(), two.hashCode())
.result();
}
}
After clarification
Okay, the question is to impose a predefined sorting order rather than sorting the Tables by name. In that case, you need to make a Comparator that is aware of the ordering defined in the .properties file.
One way to achieve this is to initialize a mapping of table names to sorting order indices, and refer that mapping during the comparison. Given the property value:
SORT_ORDER = SALES,SALE_PRODUCTS,EXPENSES,EXPENSES_ITEMS
The mapping should look like:
{
SALES: 0,
SALE_PRODUCTS: 1,
EXPENSES: 2,
EXPENSES_ITEMS: 3
}
Here's what the comparator would look like:
private static class PredefinedOrderComparator implements Comparator<Table> {
public PredefinedOrderComparator() {
// Initialize orderIndex here
}
private final Map<String, Integer> orderIndex;
#Override public int compare(Table one, Table two) {
return orderIndex.get(one.getTableName()) - orderIndex.get(two.getTableName());
}
}
To populate orderIndex from the property value, you need to:
Get the comma-separated list using getProperty() as you mentioned
Split that value on comma (I recommend using Guava's Splitter, but String.split or others will work too)
Initialize a new HashMap<String, Integer> and an int index = 0
Iterate through the split tokens, map the current token to index and increment index
Note the implicit assumption that none of the table names have a comma in it.
public class MyComparable implements Comparator<Table>{
#Override
public int compare(Table table1, Table table2) {
return (table1.getTableName().compareTo(table2.getTableName());
}
}
make sure that you have overridden the hashcode and equals in Table class to achieve this.
I wrote you a very simple example on how to work with a Comparator. If you create a class called Main, copy paste below contents in it, compile and run it, you can see what's going on.
A comparator just needs to implement an interface. For this it needs to implement one method (public int compare(T arg0, T arg1). There you specify how a collection will get sorted; in this case according to the alfabet.
I hope this helps you.
import java.util.*;
public class Main {
public static void main(String[] args) {
System.out.println("Start\n");
List<Item> items = new ArrayList<Item>();
for(String s : new String[]{"mzeaez", "xcxv", "hjkhk", "azasq", "iopiop"}) {
items.add(createItem(s));
}
System.out.println("Items before sort:");
System.out.println(Item.toString(items));
Collections.sort(items, new ItemComparator());
System.out.println("Items after sort:");
System.out.println(Item.toString(items));
System.out.println("End");
}
private static Item createItem(String s) {
Item item = new Item();
item.setS(s);
return item;
}
}
class Item {
private String s;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
#Override
public String toString() {
return "Item: " + s;
}
public static String toString(Collection<Item> items) {
String s = "";
for(Item item : items) {
s += item + "\n";
}
return s;
}
}
class ItemComparator implements Comparator<Item> {
#Override
public int compare(Item item1, Item item2) {
return item1.getS().compareTo(item2.getS());
}
}

java - return two results in one function call? [duplicate]

This question already has answers here:
How to return multiple objects from a Java method?
(25 answers)
Closed 9 years ago.
I'm trying to do something like this:
public void <String,int> getItem
{
return <"Jen",23>;
}
I know I can use a custom class, but how I would I return two results in one function call.
1 - Is the above template function possible in java, and how would by caller get part 1 of it and part 2 later.
2 - Can I do it using an associative array like in actionscript?
3 - Can I do it using a hashmap of some sort?
4 - What are other possible ways are there
I attempted all three ways, but one way or another syntax is hitting me. So if anyone can give clear examples
Java functions always return a single value, so your only option is to return a "collection" object which contains multiple values, such as an Array or a proper Collection. For example:
public Object[] getItem() { return new Object[] { "Jen", 23 }; }
public Collection<Object> { return Arrays.asList("Jen", 23); }
Although, a typical pattern in Java is to return a custom type which encapsulates your values, e.g.:
public class NameAge {
public final String name;
public final int age;
public NameAge(String name, int age) {
this.name = name;
this.age = age;
}
}
// ...
public NameAge getItem() { return new NameAge("Jen", 23); }
Or more generally:
public class Pair<X, Y> {
public final X x;
public final Y y;
public Pair(X x, Y y) {
this.x = x;
this.y = y;
}
}
// ...
public Pair<String,Integer> getItem() {
return new Pair<String,Integer>("Jen", 23);
}
Of course, there are serious implications regarding hashing (equality and hash code) if you want to use these custom types as hash keys.
I like using generics! Create your own class and return an instance of it:
public class Tuple<T,V>
{
public T item1;
public V item2;
public Tuple(T i1, V i2)
{
item1 = i1;
item2 = i2;
}
}
Then you create your method:
public Tuple<String, int> getItem()
{
return new Tuple<String, int>("Jen", 23);
}
Java does not allow for multiple return statements. The best practice I believe is to create a custom object. What you have here suggests some sort of Person class, a la
public class Person {
int Age;
String Name;
}
Returning an object will make it more intuitive what you are doing as well.
You can return a Bundle.
public Bundle getItem(){
Bundle theBundle = new Bundle();
theBundle.putString("name","Jen");
theBundle.putInt("age",23);
return theBundle;
}
Usually, if you need to return two values from one function - it's a code smell. Try to refactor your code so that every function always return just one value. Keep in mind that no return value (void) is also a code smell, but less critical.
The proper way would be to create a class for your return set:
public class ReturnSet {
private String str;
private int num;
public ReturnSet(String _str, int _num) {
str = _str;
num = _num;
}
//add getters and setters
...
}
Then your function would look like
public ReturnSet getItem() {
...
return new ReturnSet(strValue, intValue);
}
Of course, you can fudge things by having your function return an array of Object, but this would be a rather bad code:
public Object[] getItem() {
Object[] result;
//allocate it, get data;
...
result[1] = strValue;
relult[2] = new Integer(intValue);
return result;
}
You can even return a hashmap with one element in it:
public Map getItem() {
Map result;
//allocate it, say as hashmap, get data;
...
result.put(strValue, new Integer(intValue));
return result;
}
Then in the caller, the key of the map would be the first part and the value would be the second.
While there are may be many ways of doing things like that, the first one is the right approach.
If a method returns something, then its return type must be this something:
public MyCustomObject getItem();
or
public Object[] getItem():
or anything else wher you can store the results.
But Java is a statically typed OO language. A custom class is the way to go.
You can also return one value the regular way and other(s) by using a "return" parameter:
class C {
Type2 value; // omitted getter and setter for brevity
}
Type1 f1(C returnParameter, String otherParameters...)
{
// function body here
returnParameter.value=returnValue2; // store the second result
return returnValue1; // return the first result
}
// usage
Type1 result1;
Type2 result2;
C helper = new C();
result1=f1(helper, "foo", "bar");
result2=helper.value;
For more results either use several "helper" objects or one that can hold several values.
I am myself looking for a most elegant solution (in my case one return type is a Collection and the other is an integer number-any variant of it is OK).

Categories