I have a list of users, and I want to hide every user with admin role when show it in recycleview. Tried to use for method, but the app ended up crash. here is the code that I tried to use
public void setUserList(List<UserModel> userList) {
this.userList = userList;
//userList.remove(0);
for(int i=0;i<=userList.size();i++)
{
if(userList.get(i).getRole().equals("admin")) {
userList.remove(i);
}
}
//userList.removeIf(userModel -> userModel.getRole().matches("admin"));
notifyDataSetChanged();
}
For now, because the user with role admin always located at first index of array, I use userList.remove(0); but if any of you have better approach, I really apreciate it. Thank you.
Edit:
Get the answer, need to use access iterator directly.
Use Iterator
int position = 0;
Iterator<User> iter = list.iterator();
while (iter.hasNext()) {
if(iter.next().getRole().equals("admin")){
iter.remove()
}
position++
}
and in adapter
adapter.notifyItemRemoved(position)
Normal for loop should be used on collections for read only
You also need to update the Adapter. Use something like this:
for (int i = userList.size() - 1; i <= userList.size(); ++i) {
if(userList.get(i).getRole().equals("admin"))
userList.remove(i);
adapter.notifyItemRemoved(i)
}
if you getting error like this
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at beginner.HelloWorldApp.main(HelloWorldApp.java:18)
Then you can use an iterator to remove element by this way
for(Iterator<Model> iter = userList.iterator(); iter.hasNext(); ){
Model student = iter.next();
if(student.getName().equalsIgnoreCase("admin"){
iter.remove();
}
}
adapter.notifydatasetchange();
Related
So I've an adapter which takes its data from an ArrayList And I'm trying to filter the ArrayList by a few parameters that the user chooses, but the adapter doesn't update, and even makes it look like the ArrayList is empty, Any Suggestion how to fix it?
Code Below:
if (task.isSuccessful())
{
updatelist(task.getResult(), dateStr, time);
zoneAdapter.notifyDataSetChanged();
}
(Thats inside a OnCompleteListener)
updatelist:
zones.clear();
int count = 0;
for (QueryDocumentSnapshot document : result) {
zoneid = document.get(AssignmentFirebase.ZoneId).toString();
dateAssignment = document.get(AssignmentFirebase.date).toString();
timeAssignment = document.get(AssignmentFirebase.TimeSlot).toString();
if (timeAssignment.equals(time) && dateAssignment.equals(dateStr))
{
for (int i =0; i< allZones.size(); i++)
{
if (allZones.get(i).getId().equals(zoneid))
allZones.remove(i);
}
zones = (ArrayList) allZones.clone();
}
The adapter is connected to the zones ArrayList
I've used a debugger to check it in detail, seems like it deletes the zones that needs to be deleted so its probably the clone or the adapter itself, i would appreciate any help, Cheers.
The error:
java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
at WeekView.getMoreEvents(WeekView.java:614)
In a class that extends View, I get a list of the id in this way:
public void setElencoIdOperatori(int[] id_nome_op){
this.id_nome_op = id_nome_op;
}
Then, with this method, I must compare id_nome_op with eventRect.event.getIdOperatore(). When are the same, I want to add the event to the array eventRects. Thanks for your help
private void getMoreEvents(Calendar day){
// Get more events if the month is changed.
if(mEventRects ==null)
mEventRects =newArrayList<EventRect>();
if(mMonthChangeListener ==null&&!isInEditMode())
thrownewIllegalStateException("You must provide a MonthChangeListener");
// If a refresh was requested then reset some variables.
if(mRefreshEvents){
mEventRects.clear();
mFetchedMonths =newint[3];
}
...
// Get events of this month.
if(mFetchedMonths[1]<1||mFetchedMonths[1]!= day.get(Calendar.MONTH)+1||mRefreshEvents){
if(!containsValue(lastFetchedMonth,day.get(Calendar.MONTH)+1)&&!isInEditMode()){
List<WeekViewEvent> events =mMonthChangeListener.onMonthChange(day.get(Calendar.YEAR),day.get(Calendar.MONTH)+1);
sortEvents(events);
for(WeekViewEventevent: events){
cacheEvent(event);
}
}
mFetchedMonths[1]= day.get(Calendar.MONTH)+1;
}
...
// Prepare to calculate positions of each events.
ArrayList<EventRect> tempEvents =newArrayList<EventRect>(mEventRects);
mEventRects =newArrayList<EventRect>();
for(intj =1;j <=id_nome_op.length;){
ArrayList<EventRect> eventRects =newArrayList<EventRect>();
for(EventRect eventRect : tempEvents){
if(eventRect.event.getIdOperatore() == id_nome_op[j])
eventRects.add(eventRect);
}
computePositionOfEvents(eventRects);
j++;
}
}
It's a bit hard understanding your code, but I think you might have a problem here:
for(int j =1;j <=id_nome_op.length;) {
ArrayList<EventRect> eventRects =newArrayList<EventRect>();
for(EventRect eventRect : tempEvents){
if(eventRect.event.getIdOperatore() == id_nome_op[j])
eventRects.add(eventRect);
}
computePositionOfEvents(eventRects);
j++;
}
When you access id_nome_op[j].
Try changing the loop to:
j < id_nome_op.length
As #Mike M pointed out, you also need initalizing your outer loop to 0, as you want to get all the items in your array:
for(int j = 0; j < id_nome_op.length;)
I just read this from the book "Android Programming - Pushing the Limits" by Hellman, Erik. Page 38:
void loopOne(String[] names) {
int size = names.length;
for (int i = 0; i < size; i++) {
printName(names[i]);
}
}
void loopTwo(String[] names) {
for (String name : names) {
printName(name);
}
}
void loopThree(Collection<String> names) {
for (String name : names) {
printName(name);
}
}
void loopFour(Collection<String> names) {
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
printName(iterator.next());
}
}
// Avoid using enhanced for-loops for ArrayList
void loopFive(ArrayList<String> names) {
int size = names.size();
for (int i = 0; i < size; i++) {
printName(names.get(i));
}
}
These methods show four different ways of looping through collections
and arrays. The first two methods have the same performance, so it’s
safe to use the enhanced for-loop on arrays if you’re just going to
read the entries. For Collection objects, you get the same
performance when using the enhanced for-loop as when you manually
retrieve an Iterator for traversal. The only time you should do a
manual for-loop is when you have an ArrayList object.
I searched before, the foreach and the normal for loop have no performance difference in Java, is there any special reason only for Android (version 4 +)?
Please check info about for loops here
I have two lists of Default and Chrome browsers history.
I want to merge these two lists into one list.
I need to update item if I find it duplicate (is common between two lists).
So, my "BrowserRecord" class is like this:
public class BrowserRecord {
private long id;
private int bookmark;
private long created;
private long date;
private String title;
private String url;
private long visits;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BrowserRecord record = (BrowserRecord) o;
return url.equals(record.url);
}
#Override
public int hashCode() {
return url.hashCode();
}
// other getter setter methods
...
}
and finally, I have a method that gets browsers histories and does merging:
public List<BrowserRecord> getHistory() {
List<BrowserRecord> browserList = new ArrayList<BrowserRecord>();
// get history of default and chrome browsers
List<BrowserRecord> defaultList = getDefaultBrowserHistory();
List<BrowserRecord> chromeList = getChromeBrowserHistory();
Log.e(TAG, "=> size of Default browser:" + defaultList.size());
Log.e(TAG, "=> size of Chrome browser:" + chromeList.size());
// compare list A with B, update A item if equal item found in B and push it to tempList
for(int i=0; i<chromeList.size(); i++) {
BrowserRecord chromeBrowser = chromeList.get(i);
for(int j=0; j<defaultList.size(); j++) {
BrowserRecord defaultBrowser = defaultList.get(j);
if(chromeBrowser.equals(defaultBrowser)) {
if(chromeBrowser.getBookmark() != defaultBrowser.getBookmark())
chromeBrowser.setBookmark(1);
chromeBrowser.setVisits(chromeBrowser.getVisits() + defaultBrowser.getVisits());
}
}
browserList.add(chromeBrowser);
}
// compare list B with A, jump if equal item found in A, push to tempList if item not found
for(int i=0; i<defaultList.size(); i++) {
BrowserRecord defaultBrowser = defaultList.get(i);
boolean found = false;
for(int j=0; j<chromeList.size(); j++) {
BrowserRecord chromeBrowser = chromeList.get(j);
if(defaultBrowser.equals(chromeBrowser)) {
found = true;
break;
}
}
if(!found)
browserList.add(defaultBrowser);
}
Log.e(TAG, "=> size of final browser:" + browserList.size());
return browserList;
}
I have tested this method and is working fine. Since my history records on mobile device after 3 years didn't exceed more than 200 records on one list and 150 for others, I assume something similar is happening for other users. But I'm sure is not optimum way.
What do you recommend?
any suggestion would be appreciated. Thanks.
Not sure I understand correctly, but it seems like what you're trying to do is, given both lists, create a final list which will contain all of the elements from both lists, removing any duplicates.
If this is the case, then take a look at Java's TreeSet class. If you iterate over all of the elements from both your lists and insert them into a TreeSet, you will basically get the result you're looking for. You can then use an Iterator to create an ArrayList containing all of the non-duplicate items from both your lists. As a side-effect of using a TreeSet, they will ordered (you can also use either a HashSet if you don't care about the order or a LinkedHashSet if you want to preserve the order of insertion).
I have an array adapter(string), and would like to convert it to a List<String>, but after a little googling and a few attempts, I am no closer to figuring out how to do this.
I have tried the following;
for(int i = 0; i < adapter./*what?*/; i++){
//get each item and add it to the list
}
but this doesn't work because there appears to be no adapter.length or adapter.size() method or variable.
I then tried this type of for loop
for (String s: adapter){
//add s to the list
}
but adapter can't be used in a foreach loop.
Then I did some googling for a method (in Arrays) that converts from an adapter to a list, but found nothing.
What is the best way to do this? Is it even possible?
for(int i = 0; i < adapter.getCount(); i++){
String str = (String)adapter.getItem(i);
}
Try this
// Note to the clown who attempted to edit this code.
// this is an input parameter to this code.
ArrayAdapter blammo;
List<String> kapow = new LinkedList<String>(); // ArrayList if you prefer.
for (int index = 0; index < blammo.getCount(); ++index)
{
String value = (String)blammo.getItem(index);
// Option 2: String value = (blammo.getItem(index)).toString();
kapow.add(value);
}
// kapow is a List<String> that contains each element in the blammo ArrayAdapter.
Use option 2 if the elements of the ArrayAdapter are not Strings.