Delete duplicates in arraylist - java

I have a ListView with a custom ArrayAdapter with a custom object. The ListView contains headers. I loop through to get the header names on my custom objects. Some of them have the SAME value for headerTitle. I do NOT want them to get added to the row if that header already exists. This is my code (in my ArrayAdapter) to try and see if the same header has been added but it does absolutely nothing:
public static List<FriendsVideoLVModel> list = new ArrayList<FriendsVideoLVModel>();
#Override
public void add(FriendsVideoLVModel obj) {
super.add(obj);
for (int i=0; i <list.size(); i++) {
if (!obj.eventTitle.equals(list.get(i).eventTitle)) {
list.add(obj);
notifyDataSetChanged();
}
}
}

Related

GWT - CellTable sortable column won't respond to clicks

I have a GWT Celltable column that needs to be sorted alphabetically. I followed the official documentation and other questions posted here, but I have not been able to get it to work.
I want the column to sort both ascending and descending. Currently, the carat symbol shows up next to the column header but nothing happens when it is clicked. There are no errors being thrown in the browser console either.
What am I doing wrong? My obfuscated code -
public class MyClass extends Composite {
//other fields
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
#UiField CellTable<MyObject> myTable = new CellTable<MyObject>();
final ListDataProvider<MyObject> myDataProvider = new ListDataProvider<MyObject>();
#UiConstructor
public MyClass(...) {
initWidget(uiBinder.createAndBindUi(this));
// other initialization
buildMyTable();
}
buildMyTable() {
myDataProvider.addDataDisplay(myTable);
Column<MyObject, String> colA = new Column<MyObject, String>(new TextCell()) {
#Override
public String getValue(MyObject object) {
return object.getName();
}
};
Column<MyObject, String> colB = new Column<MyObject, String>(new TextCell()) {
#Override
public String getValue(MyObject object) {
return object.getAddress();
}
};
// created other columns
colA.setSortable(true);
myTable.addColumn(colA, "COL A");
myTable.addColumn(colB, "COL B");
// added other columns to the table
ListHandler<MyObject> columnSortHandler = new ListHandler<>(myDataProvider.getList());
columnSortHandler.setComparator(colA, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
if (o1 == o2) {
return 0;
}
if (o1 != null) {
return (o2 != null) ? o1.getName.compareTo(o2.getName) : 1;
}
return -1;
}
});
myTable.addColumnSortHandler(columnSortHandler);
myTable.getColumnSortList().push(colA);
ColumnSortEvent.fire(myTable, myTable.getColumnSortList());
}
}
It is all about how do you add data to the CellTable. For example, you can
myDataProvider.setList(rowData);
or
myTable.setRowData(rowData);
but both above methods will not allow the data to be sorted. That is because, you already have ListHandler defined with an empty list. And it will not notice that the list have changed, so no sorting will be performed.
See ListDataProvider documentation:
Modifications (inserts, removes, sets, etc.) to the list returned by getList() will be reflected in the model. However, mutations to the items contained within the list will NOT be reflected in the model. You must call List.set(int, Object) to update the item within the list and push the change to the display, or call refresh() to push all rows to the displays. List.set(int, Object) performs better because it allows the data provider to push only those rows which have changed, and usually allows the display to re-render only a subset of the rows.
So, you should first getList() and change it like this:
myDataProvider.getList().clear();
myDataProvider.getList().addAll(rowData);

Search an ArrayList Model

I want to get all items that contains the search input based on itemName. In c#, I can use lambda, but I could not find any references for android.
Here is the model class:
public class ModelItem {
public long itemId;
public String itemName;
public double price;
}
Here is my list:
public static ArrayList<ModelItem> items;
I will use the list to get the items. Thank you in advance.
Use below code
public void getAllItems(ArrayList<ModelItem> items, String searchItem) {
for(ModelItem item : items) {
if(item.getItemName().contains(searchItem)) {
// here you are getting item which matches inside your list
}
}
I think you have a listview with items. Now you want to filter them with a search string.
You have to implement Filterable in your custom adapter.
How to filter an adapter
First step, copy items into tempList
private ArrayList<ModelItem> items; // You have data into this list
private ArrayList<ModelItem> tempData = new ArrayList<>();
for (ModelItem item : items) {
tempData.add(item);
}
This is to filter items based on query
public void filter(String query) {
items.clear();
if (query.length() > 0) {
for (ModelItem currItem : tempData) {
// Add data into list, if item is having query string
if (currItem.getItemName().toLowerCase().contains(query)) {
mData.add(currItem);
}
}
} else {
// Adding all the items, if query is empty
for (ModelItem item : tempData) {
items.add(item);
}
}
notifyDataSetChanged(); // notify the changes, if you are using an adapter.
}
hey i got a example for your requirement in github, you need to use QueryTextListener in main class, then setFilter to adapter as given in example
please check this link:https://github.com/Wrdlbrnft/Searchable-RecyclerView-Demo

How can I add a value to an ArrayList from an inner method?

I am currently trying to add a value to an ArrayList object from a method inside of another class.
Here is the class I have created for the ArrayList Object:
public class ArrayClass {
public static ArrayList<String> array = new ArrayList<>();
public static void add_val(String s){
array.add(s);
}
public static int get_size(){
return array.size();
}
public static String get_val(int i){
return array.get(i);
}
}
And the other class where I attempt to edit the ArrayList object:
ArrayClass fill = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_explore);
Response.Listener<String> responseListener4 = new Response.Listener<String>(){
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse4 = new JSONObject(response);
boolean success = jsonResponse4.getBoolean("success");
if (success){
int l;
String filled;
int length4 = jsonResponse4.length();
for (l=0;l<length4;l++){
filled = jsonResponse4.getString(l+"");
fill.add_val(filled);
}
}else{
AlertDialog.Builder builder = new AlertDialog.Builder(ExploreActivity.this);
builder.setMessage("Could not retrieve restaurant tables filled")
.setNegativeButton("Retry", null)
.create()
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
FilledRequest filledRequest = new FilledRequest(responseListener4);
RequestQueue queue4 = Volley.newRequestQueue(ExploreActivity.this);
queue4.add(filledRequest);
If you look in the onResponse method, you can see the attempt to add a value from the jsonResponse into the ArrayClass object. However, when I launch my app, it does not add the value into the object. I'm used to python global variables and not having to deal with the semantics of java, so if you could shed some light on what changes need to be made, I would greatly appreciate it.
Apart from other given answers/solutions to the issue you are facing, let me share a best and optimized way to implement JSON parsing in Android.
I would suggest you to check GSON or Jackson libraries which provides Java serialization/deserialization that can convert Java Objects into JSON and back.
There are some benefits it does provide, one of the main benefits is you do not need to implement parsing manually and less chances of mistakes in implementing parsing, like you may make a mistake in mentioning key "Success" or "success" or any such silly mistakes!
Firstly, since your variable is static, and the methods are static too, you don't have to instantiate the object. You could do something like this:
ArrayClass.add_val("Hello");
But if you want to instantiate then you can do this:
public class ArrayClass {
private ArrayList<String> array;
public ArrayClass() {
array = new ArrayList<>();
}
public void add_val(String s){
array.add(s);
}
public int get_size(){
return array.size();
}
public String get_val(int i){
return array.get(i);
}
}
To make sure the values are filled in, you can check the array size like this:
for (l=0;l<length4;l++){
filled = jsonResponse4.getString(l+"");
fill.add_val(filled);
}
Log.d("TEST", String.valueOf(fill.get_size());
Remove all cases of the static keyword in ArrayClass. Static methods are class level methods, ie. are called on the class itself, rather than an instance of the class.
You can also try this, for ArrayList:
First do some changes in your ArrayClass. Use get And Set method to access your array.
public class ArrayClass {
private ArrayList<String> array = new ArrayList<>();
public ArrayList<String> getArray() {
return array;
}
public void setArray(ArrayList<String> array) {
this.array = array;
}
}
And your other class where you attempt to edit the ArrayList use getArray And SetArray method and some predefined method of ArrayList like this:
Store the data in ArrayList:
for (l=0;l<length4;l++){
filled = jsonResponse4.getString(l+"");
fill.getArray().add(filled);
}
Get Size of ArrayList:
fill.getArray().size();
And also you can store an another ArrayList like
ArrayList<String> tempArrayList = new ArrayList<String>();
tempArrayList.add("string 1");
tempArrayList.add("string 2");
tempArrayList.add("string 3");
tempArrayList.add("string 4");
fill.setArray(tempArrayList)

Deleting item from ArrayAdapter

I have an array: Object[] array, and an array adapter that extends ArrayAdapter<Object>.
When i try to delete from it using adapter.remove(Object obj) i get an UnsupportedOperationException exception, just as this post.
The provided answers suggest using an ArrayList instead. This is not an option for me. I need to stick with array. So i copied the array to another array, but without the item i want to delete. Then i just did:
oldArray = newArray;
and then called adapter.notifyDataSetChanged();.
This works fine except it doesn't refresh the screen. I need to close then reopen the screen to see the changes. Shouldn't notifyDataSetChanged() do the refreshing?
edit:
Following #MD's answer, this is what i'm doing right now:
controller.onRemove(id);
public void onRemove(int id) {
int userListLength = usersArray.length;
int j = 0;
User[] newUserList = new User[userListLength-1];
for(int i=0; i<userListLength; i++)
{
if(id != usersArray[i].getId())
{
newUserList[j] = new User();
newUserList[j] = usersArray[i];
j++;
}
}
usersArray = newUserList;
//store in database
//...
view.getAdapter().refresh( usersArray );
}
public void refresh(User[] items)
{
this.userArray = items;
notifyDataSetChanged();
}
adapter construction:
adapter = new myUserAdapter( controller.getBaseContext(), R.layout.user_row, userArrayList);
usersListView.setAdapter( adapter );
and in myUserAdapter i have:
private User[] userArray;
Solution:
#MD's answer works. But I also had to override getCount() in the adapter:
#Override
public int getCount () {
return userArray.length;
}
It's explained in the accepted answer here.
i have a way
Add refresh method in your adapter:
public void refresh(List<String> items)
{
this.items = items;
notifyDataSetChanged();
}
and call from Activity like
yourAdapter.refresh(items); // items new arrayList or Array
ArrayAdapter simply wraps the List<T> you pass to its constructor and when you call remove(), it calls the remove() method of that list.
If you pass an array instead of a list to the constructor, it converts it with Arrays.asList().
/**
* Constructor
*
* #param context The current context.
* #param resource The resource ID for a layout file containing a TextView to use when
* instantiating views.
* #param objects The objects to represent in the ListView.
*/
public ArrayAdapter(Context context, int resource, T[] objects) {
init(context, resource, 0, Arrays.asList(objects));
}
In older Android versions Arrays.asList returns a readonly list. That's why you get the exception
You must explicitly create an ArrayList out of your array:
adapter = new myUserAdapter( controller.getBaseContext(), R.layout.user_row, new ArrayList<User>(Arrays.asList(userArrayList)));

ArrayAdapter contains an object based on a value

I have a ListView and ListView adapter. I am adding objects to the adapter but I only want to add one row with an object that contains a certain String. This is my code but it does not work:
public static List<FriendsVideoLVModel> list = new ArrayList<FriendsVideoLVModel>();
#Override
public void add(FriendsVideoLVModel obj) {
super.add(obj);
for (int i=0; i <list.size(); i++) {
if (!obj.eventTitle.equals(list.get(i).eventTitle)) {
list.add(obj);
notifyDataSetChanged();
}
}
}
Please help. The logic looks fine to me but it just does not work. Nothing is in fact added.

Categories

Resources