Android ArrayList compare - android

Hi guys i got 2 ArrayList based on same class. I have to add from arraylist1 to arraylist2 non exist(s)ing rows. I tried to use contains but its always returning false. What i m doing wrong ? Ty
MyClass
public class HataKoduBean {
private String Oid;
private String Name;
private String Surname;
}
How i define Arraylists
Arraylist<MyClass> array1 = new Arraylist<>();
Arraylist<MyClass> array2 = new Arraylist<>();
How i tried to compare ?
for (int ii = 0; ii < array1.size(); ii++) {
if (!array2.contains(array1.get(ii)))
array2.add(array1.get(ii));
}

First you have to implement equals() and hashCode() in your custom class.
Consider to use Sets, so you can merge collections in one line with addAll().

First you have to implement equals() and hashCode() in your custom object
and create loop and compare between object by using equals method like this.
implement equals and hashCode:
`#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
HataKoduBean o = (HataKoduBean) o;
return Oid != null?Oid.equals(HataKoduBean.Oid):HataKoduBean.Oid== null;
}
#Override
public int hashCode() {
return Oid != null ? Oid.hashCode() : 0;
}`
compare Objects:
for (int ii = 0; ii < array1.size(); ii++) {
if (!array2.get(ii).equals(array1.get(ii)))
array2.add(array1.get(ii));
}

Related

Compare elements of two arraylist of different sizes and order in android

I am not getting the result true even when the first element of both arraylists are same.i want to check my checkbox when result matches.I have implemented it in my recyclerview I want to compare the elements of the arraylists but both are different in size.I found a solution online and implemented it like:.
List<String> list1 = new ArrayList<>();
for (int i = 0; i < data.size(); i++) {
list1.add(data.get(i).getChannel_names());
}
List<String> list2 = new ArrayList<>();
for (int i = 0; i < listNewsChannelsSelected.size(); i++) {
list2.add(listNewsChannelsSelected.get(i).getSelectedChannelsFromApi());
}
private boolean equalLists(List<String> one, List<String> two) {
if (one == null && two == null) {
return false;
}
if (one != null && two == null) {
return false;
}
one = new ArrayList<>(one);
two = new ArrayList<>(two);
Collections.sort(one);
Collections.sort(two);
return one.equals(two);
}
if (equalLists(list1,list2)) {
holder.mCheckBox.setChecked(true);
} else {
holder.mCheckBox.setChecked(false);
}
I just tested it and saw that there is nothing wrong in the code. (Bit modified to test in java). I am getting the result as TRUE so the code is correct.
Try to check your API data. It seems to be incorrect (not what you are expecting it to be). Try to generate logs (print api data in loop).
public class Main {
public static void main(String args[]){
List<String> list1 = new ArrayList<>();
for (int i = 0; i < 5; i++) {
list1.add(""+i);
}
List<String> list2 = new ArrayList<>();
for (int i = 0; i < 5; i++) {
list2.add(""+i);
}
if (equalLists(list1,list2)) {
System.out.println("TRUE");
} else {
System.out.println("FALSE");
}
}
private static boolean equalLists(List<String> one, List<String> two) {
if (one == null && two == null) {
return false;
}
if (one != null && two == null) {
return false;
}
one = new ArrayList<>(one);
two = new ArrayList<>(two);
Collections.sort(one);
Collections.sort(two);
return one.equals(two);
}

copyToRealm copies an empty list instead of a populated one

I have a RealmObject called "Encounter", which contains a RealmList of other RealmObjects called "SavedCombatant". In my code, I populate the RealmList with the appropriate objects, but when I commit the transaction and retrieve the Encounter-Object later, the RealmList is empty.
I have the following code
public void saveEncounter(){
//create a new key for the encounter
int key = 0;
if(mRealm.where(Encounter.class).count() != 0) {
RealmResults<Encounter> encounters = mRealm.where(Encounter.class).findAll();
Encounter encounter = encounters.last();
key = encounter != null ? encounter.getKey() + 1 : 0;
}
// retrieve the data to populate the realmlist with
// combatants has 1 element
List<SavedCombatant> combatants = mAdapter.getCombatants();
mRealm.beginTransaction();
Encounter e = mRealm.createObject(Encounter.class);
e.setKey(key);
e.setTitle(txtTitle.getText().toString());
RealmList<SavedCombatant> combatantRealmList = new RealmList<>();
for (int i = 0; i < combatants.size(); i++) {
combatantRealmList.add(combatants.get(i));
}
//combatantRealmList also has 1 element. setCombatants is a
//generated Setter with a couple bits of additional logic in it
e.setCombatants(combatantRealmList);
mRealm.copyToRealm(e);
mRealm.commitTransaction();
}
this would be my Encounter class
public class Encounter extends RealmObject {
private int key;
private String title;
private RealmList<SavedCombatant> combatants;
#Ignore
private String contents;
public void setCombatants(RealmList<SavedCombatant> combatants) {
//simple setter
this.combatants = combatants;
//generate summary of the elements in my realmlist. (probably inefficient as hell, but that's not part of the problem)
HashMap<String, Integer> countMap = new HashMap<>();
for (int i = 0; i < combatants.size(); ++i) {
String name = combatants.get(i).getName();
int countUp = 1;
if (countMap.containsKey(name)) {
countUp = countMap.get(name) + 1;
countMap.remove(name);
}
countMap.put(name, countUp);
}
contents = "";
Object[] keys = countMap.keySet().toArray();
for (int i = 0; i < keys.length; ++i) {
contents += countMap.get(keys[i]) + "x " + keys[i];
if (i + 1 < keys.length)
contents += "\r\n";
}
}
// here be more code, just a bunch of getters/setters
}
the class used for the RealmList has the following header (as to verify that I'm using a RealmObject here aswell)
public class SavedCombatant extends RealmObject
As it turns out, you need to explicitly save Objects inside a RealmList.
I needed to copy my SavedCombatant object to realm inside my for loop, using
mRealm.copyToRealm(combatants.get(i));

contains in HashSet<int[]>()

In android I'm trying to save grids that the user already have pressed.
Code snipping I’m using is:
// private
private HashSet<int[]> PlayerSelectedHashField = new HashSet<int[]>();
private boolean collisionDetected = false;
In a function I’m using
collisionDetected = PlayerSelectedHashField.contains(TmpPos); // -> Fail - not working
{doing something}
PlayerSelectedHashField.add(TmpPos); // int[] TmpPos - TmpPos is x y
The .add function is working as expected, but .contains always return false.
Why does it not working - and what can I do instead?
public boolean contains(Object o) {
return map.containsKey(o);
}
containsKey:
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
getNode:
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
It will not work since equals of arrays will do a == compare, and it will return true only if they point to the same instance.
Your problem could be fixed without work with Arrays.equals (the way to compare two arrays elements and not reference) (could be problematic (at least, for me.) i prefer an easy way)
Since you save X and Y coordinates, just make a class Point
public class Point {
public final int X;
public final int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
#Override
public boolean equals(Object obj)
{
if (obj == this) {
return true;
}
if (obj instanceof Point) {
Point pObj = (Point) obj;
return pObj.X == X && pObj.Y == Y;
}
return false;
}
#Override
public int hashCode()
{
int result = X;
result = 31 * result + Y;
return result;
}
}
then use Point class to save X, Y points.
Instead of create your custom point class, you can use the Android Point.
Example
Set<Point> points = new HashSet<Point>();
points.add(new Point(1, 3));
points.add(new Point(1, 4));
System.out.println(points.contains(new Point(1, 3)));
System.out.println(points.contains(new Point(1, 4)));
System.out.println(points.contains(new Point(1, 5)));
From the HashSet javadocs:
public boolean contains(Object o)
Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).
So, generally, if you don't know what happens when you call equals on a particular object type, then contains also may not behave as you expect. It is never a bad idea to make a class for a particular object if that object type has conceptual meaning in your program. If you do that, you can override the equals method to make sure it is behaving exactly as you want.

indexOfValue(E) of SparseArrayCompat always return -1?

indexOfValue(E) method always return -1 while I am sure my E object exists in my SparseArray object, why? I have :
static final SparseArrayCompat<Long> LOCATION_SHARING_TIME = new SparseArrayCompat<Long>();
static {
LOCATION_SHARING_TIME.put(0, LOCATION_SHARING_TIME_5s);
LOCATION_SHARING_TIME.put(1, LOCATION_SHARING_TIME_1m);
LOCATION_SHARING_TIME.put(2, LOCATION_SHARING_TIME_5m);
LOCATION_SHARING_TIME.put(3, LOCATION_SHARING_TIME_30m);
LOCATION_SHARING_TIME.put(4, LOCATION_SHARING_TIME_1h);
}
I cannot use SparseLongArray because it support API 18+ which my project support API 9 minimum.
Because it uses == instead of equal to determine the equality. See the implementation of the method:
public int indexOfValue(E value) {
if (mGarbage) {
gc();
}
for (int i = 0; i < mSize; i++)
if (mValues[i] == value)
return i;
return -1;
}
One idea would be to extend the SparseArray and override the method replacing == with equal.
public int indexOfValue(E value) {
if (mGarbage) {
gc();
}
for (int i = 0; i < mSize; i++)
if (mValues[i].equals(value))
return i;
return -1;
}

Sorting list in alphabetical order

Im working on an application where I create a list with the installed apps and let the user select one. I've got everything working except for one thing; ordering them in alphabetical order. Here's the code I'm using:
private List<App> loadInstalledApps(boolean includeSysApps) {
List<App> apps = new ArrayList<App>();
PackageManager packageManager = getPackageManager();
List<PackageInfo> packs = packageManager.getInstalledPackages(0);
for(int i=0; i < packs.size(); i++) {
PackageInfo p = packs.get(i);
App app = new App();
app.setTitle(p.applicationInfo.loadLabel(packageManager).toString());
app.setPackageName(p.packageName);
app.setVersionName(p.versionName);
app.setVersionCode(p.versionCode);
CharSequence description = p.applicationInfo.loadDescription(packageManager);
app.setDescription(description != null ? description.toString() : "");
apps.add(app);
}
return apps;
}
Any help is appreciated!
Use Comparator to sort data ...
Collections.sort(apps, new Comparator<App>() {
#Override
public int compare(App lhs, App rhs) {
//here getTitle() method return app name...
return lhs.getTitle().compareTo(rhs.getTitle());
}
});
First: create comparator
Public class App implements Comparable {
// Lista de atributos y métodos
public int compareTo(Object o) {
// logic of comparation
return result; //must be integer
}
}
For example:
public int compareTo(Object o) {
Direccion dir = (Direccion)o;
if(this.name < app.getName())
return -1;
else if(this.name == app.getName())
return 0;
else
return 1;
}
And when you want to short, use Collections.short(list)
Simpliest solution
Collections.sort(familleList, (famille, t1) -> famille.compareTo(t1));
In Kotlin using lambda expression and comparator. you can easily sort your list alphabetically.
yourList.sortWith(Comparator { obj1, obj2 ->
obj1.name.compareTo(obj2?.name!!, ignoreCase = true)
})
Note: Here obj1 and obj2 is Model object of your list. e.g
val yourList: MutableList<Model> = ArrayList()

Categories

Resources