how to ensure an arrayadapter does not accept duplicate values - java

i have a custom arrayadapter with some pre_populated data and more data is to be added to it from the user input.The problem is that duplicate values are still added to the arrayadapter..here is my code:
String s;//holds data from user input
for(int i=0 ; i<my_adapter.getCount() ; i++){
MyCollection itemObject=my_adapter.getItem(i);
//MyCollection is an object from the collection class
String c=itemObject.toString();
if(c.matches(s)){
//do not add s to array adapter
}else{
//add s to arrayadapter
my_arrayvalues.add(new MyCollection(s));
my_adapter.notifyDataSetChanged();
}
Running the above code,no change is effected on the adapter even when the the values do not match..if i just run the project without including the above
duplicate values are added.how can i correct this?
after following the answers i have done as suggested but still the duplicates are being added:
the updated code
hs = new HashSet();
my_arrayvalues.add(new MyCollections(s));
hs.addAll(my_arrayvalues);
my_arrayvalues.clear();
my_arrayvalues.addAll(hs);
my_adapter.notifyDataSetChanged();

you can use a Collection that does not allow duplicates. Since you have implemented your custom adapter you can avoid to pass to the super constructor of ArrayAdapter the dataset, and override the methods you need.
For instance you could use a
LinkedHashSet
and the getCount method should returns the this of the LinkedHashSet. Also, your class could extend BaseAdapter instead of ArrayAdapter

Use String.equals(s) instead of String.matches(s).
Equals will compare the string objects for equality.
String s;//holds data from user input
for(int i=0 ; i<my_adapter.getCount() ; i++){
MyCollection itemObject=my_adapter.getItem(i);
//MyCollection is an object from the collection class
String c=itemObject.toString();
if(c.equals(s)){
//do not add s to array adapter
}else{
//add s to arrayadapter
my_arrayvalues.add(new MyCollection(s));
my_adapter.notifyDataSetChanged();
}
!!!EDIT!!!
While the above should fix your problem, I agree with others solution that you should use a HashSet instead of checking all elements manually. Using HashSet or equivalent will improve performance. Check this answer for a better explanation.

Related

Fetching and modifying an object in a set in Java

I have MyFinalSalad class consisting of the following elements:
AppleClass apple;
BananaClass banana;
PearClass pear;
List<SpicesClass> spices;
I have equals implemented such as 2 MyFinalSalad objects are equal, if they have same AppleClass, BananaClass, PearClass objects in them.
Now, I am creating a set of MyFinalSalad objects.
And I have the following code:
MyFinalSalad mySalad = new MyFinalSalad(apple, banana, pear);
SpiceClass cinnamon = new SpiceClass("cinnamon");
if (mySet.contains(mySalad)) {
// I want to fetch mySalad object in the set and add cinnamon to the list of spices
} else {
List<SpiceClass> spices = new ArrayList<>();
spices.add(cinnamon);
mySalad.setSpices(spices);
mySet.add(mySalad);
}
To summarize, if mySalad is already present in mySet, add the spice object to the list of spices in mySalad from mySet, else add mySalad to mySet after creating a new spice list, adding cinnamon to it and inserting list in mySalad.
My question is, if set already has mySalad and I want to add a new spice to the list in that object, how do I achieve it?
From https://stackoverflow.com/a/7283419/887235 I have the following:
mySet.stream().filter(mySalad::equals).findAny().orElse(null).getSpices().add(cinnamon);
Is this the only way or the right way to do it? Or is there a better way?
I was thinking that as I am already entering if after doing a contains check, orElse(null) will never be encountered. Thus null.getSpices() will never occur. Is this assumption correct?
Is there a better way to do it?
I cannot change Set to Map.
Your assumption is correct. The orElse(null) will never take place since you check if the set contains the salad right before. You could replace it with get().
However, I would also go one level before and handle it as an Optional, taking the advantage of isPresent and get method.
Salad mySalad = new Salad();
Optional<Salad> possibleSalad = set.stream().filter(mySalad::equals).findAny();
if (possibleSalad.isPresent()) {
Salad alreadyExistingSalad = possibleSalad.get();
// combine spices
} else {
// add new salad
}

How to remove new ArrayList<>?

I have try methods like remove, removeAll, delete. But all of these words is not available in android studio. What word should i used instead?
public List<ContactObject> receipt = new ArrayList<>();
receipt.add(new ContactObject(object.product_title, object.product_price,
object.img1, object.quantity));
I know how to add to the list receipt, but how to remove the data added?
The remove() of an ArrayList depends on the implementation of equals() method, in your case in ContactObject.
Invoking remove() then will solve your issue.
receipts.remove(contactObject);
If you don't add the new object directly, you can remove it like this:
List<ContactObject> receipts = new ArrayList<>();
ContactObject contactObject = new ContactObject(object.product_title, object.product_price,
object.img1, object.quantity)
receipts.add(contactObject);
// Remove previous added object
receipts.remove(contactObject);
removeAll removes all the given objects and returns the state of the operation.while remove only remove the object that is currently provided.
In your case you want to remove a single object by
yourarraylist.remove(yourobject);

ParseQuery: convert from list of prices in database to strings android

​Hi All,
I am trying to build a scrolling custom listview that displays a list of products ordered by Price ascending. However I just realized I was storing the prices as strings which means $1000.00 comes before $2.01 because it is a character and not a number. I have converted my data to a "Number" on Parse and believe the best type to retrieve it is a double (can anyone comment on that for dollar amounts). The problem is I need to keep it as a number convert it to a string and then pass it to the listview for display on a text field. Initially i had
PPI.setProductprice((String) product.get("Price"));
like this:
// Locate the class table named "Products" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Products");
// Locate the column named "Price" in Parse.com and order list
// by ascending
query.orderByAscending("Price");
ob = query.find();
for (ParseObject product : ob) {
// Locate images in PrimaryPhoto column
ParseFile productimage = (ParseFile) product.get("PrimaryPhoto");
ProductPopulation PPI = new ProductPopulation();
PPI.setProductname((String) product.get("Name"));
PPI.setProductbrand((String) product.get("Brand"));
PPI.setProductprice((String) product.get("Price"));
PPI.setProductimage(productimage.getUrl());
productpopulationlist.add(PPI);
I then tried putting it into an array of doubles an iterating through it to convert to strings.
My last attempt which probably doesn't make sense was to change it like this:
PPI.setProductprice((Double) product.getDouble("Price"));
I am fairly knew to Android and any help you can give me would be appreciated.
Thanks in advance.
OK so i do not get the context here but what you can do is save the price as a string and when extracting it you could call Integer.parseInt(String intvalue); on the string to convert the value back to int then you can do all operations you ought to do. you can get a disordered array from the server and arrange it at device level that will save you some time and logic.
I don't know what is the ProductPopulation class you use to populate the list, so I can not say what exactly is the best way in your case, but in general a list can be ordered by means of the Collections.sort() method (see the method documentation).
You could sort the list before you add it to your list view. To sort a list the way you need, you must provide a comparator, than obtains the required values (fields or method results) from the objects that comprise your list, compares the obtained values and returns -1, 0, or 1, depending on the comparison result.
It could look somewhat like this:
for (...) {
ItemClass newObject = new ItemClass(); // new list item
// ...here add the values to the list item...
theList.add(newObject); // add the new item to the list
}
// now sort the list before adding it to the list viewer
Collections.sort(theList, new Comparator<ItemClass>() {
#Override
public int compare(ItemClass o1, ItemClass o2) {
// obtain and compare the values you need
return Double.compare(o1.getDouble(), o1.getDouble());
// you could also do something like
// Double.compare(
// Double.parseDouble(o1.getString()),
// Double.parseDouble(o2.getString()));
// but it would be much slower
}
});
// now add the sorted list to the viewer
listViewer.setList(theList);

ConcurrentModificationExample and possible code simplification

I am throwing a ConcurrentModificationExample in the following code. I checked the API and it has to do with me trying to modify an object while another thread is iterating over it. I am clueless on the matter. I have created a comment above the line causing the exception. The Employee class doesn't contain anything other than the three variables for storing information.
I will be including the entire class as I would also like to know if there is a way to simplify my code as it repeats many things such as object creation and adding everything to the lists.
When you call employeesByAge in here with dep.employees:
dep.employeesByAge(dep.employees)
that will pass in dep.employees to employeesByAge such that in:
public class Department{
LinkedList<Employee> employees = ...;
public LinkedList<Employee> employeesByAge(LinkedList<Employee> outputList) {
...
}
}
both the employee member field and the outputList parameter refers to the same list, not just two list with the same content, but the same list instance.
Then you do:
for (Employee emp: employees){
//the list is null. add the first employee
if (outputList.isEmpty()){
outputList.add(emp);
} else
...
}
which iterates the employee and modifies outputList, but remember that these two are the same list object. Thus, ConcurrentModificationException.
What you're attempting to do is similar to this...
List list = ...;
for(item: list) {
list.add(item);
}
That is, you're updating a collection with elements by iterating over the same collection. All
outputList.add(...);
in Department are adding elements to the collection from the same collection 'employees'.
In main(), by doing
dep.employeesByAge(dep.employees)
you're attempting to update 'dep.employees' with 'dep.employees.' which results in concurrent modification exception.

how to add a list to another list while looping?

I have a list which has object(record) taken from database. I need to add it another list of generic class inside a loop.When ever loop executes the final list contains only the last element.my coding are..
List<modelclass> mdlclasslist=new ArrayList();
for(Class_1 a:class1list) {
Query qr=s.createQuery("from Class_2 where ID= :f and code= :j order by mark desc");
qr.setParameter("f",id);
qr.setParameter("j",code);
List<Class_2> b=new ArrayList();
b=qr.list();
for(Class_2 cls:b) {
modelclass mdl=new modelclass(cls.getID(),cls.getCode(),cls.getMark());
mdlclasslist.add(mdl);
}
}
mdlclasslist contains same object.It is not adding every object the query takes.please advice.
Your Query appears to return the same list over and over again for every Class_1 item because id and code never change. I assuming your code should rather look like this:
Query qr=s.createQuery("from Class_2 where ID= :f and code= :j order by mark desc");
for( Class_1 a : class1list )
{
qr.setParameter( "f", a.id );
qr.setParameter( "j", a.code );
for( Class_2 cls: qr.list() )
{
modelclass mdl=new modelclass(cls.getID(),cls.getCode(),cls.getMark());
mdlclasslist.add(mdl);
}
}
How about debugging and printing out the number of elements in the 2nd list before adding?
Not sure if you want to append the List you retrieve from a DB to the one you initialize beforehand...
However, I would define the 1st List to be of the generic type Class_1 (BTW: read about Java naming conventions) and then use addAll
yourList.addAll(theListFromDB);
try this
listInstance.addAll(anotherListInstavce) ;
First i would check if my source list, the one populated from DB has more than 1 element. If you are using JDBC, its a very common mistake to not move the result set objects further.
Secondly if you need such collection manipulation utilities i suggest take a look at commons-collections ListUtils class.
All the collections have a simple method to add data of one collection to other.
list2.addAll(list1);
You can simply use this method...

Categories