Dear all i am comparing two List in android if both values are same and it is returning true that is fine but i want to know how many values have been correct between the list string if it is not matching how to achieve this Help is appreciated. Below is my code.
List<String> list1 = new ArrayList<String>(i1.values());
///list 1 = [-ful; to be full of; play; playful; full of play]
List<String> acct_Rte_Cdes_A = Arrays.asList(result) ;
///acct_Rte_Cdes_A = [-ful; to be full of; play; playful; full of play]
if (list1.equals(acct_Rte_Cdes_A)) {
// do what you want to do if the string is there
//System.out.println("True");
} else {
System.out.println("False");
}
Use Collection#retainAll(). like
List<Integer> common = new ArrayList<Integer>(listA);
common.retainAll(listB);
// common now contains only the elements which are contained in listA and listB.
So you can check for size if it is greater than 0 it meanse some elements are common. And which are common elements common will tell.
You can use containsAll method on Java collection. Here is an example.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainClass {
public static void main(String[] a) {
String elements[] = { "A", "B", "C", "D", "E" };
List<String> list = new ArrayList<String>(Arrays.asList(elements));
elements = new String[] { "A", "B", "C" };
List<String> list2 = new ArrayList<String>(Arrays.asList(elements));
System.out.println(list.containsAll(list2)); // true
System.out.println(list2.containsAll(list)); // false
}
}
Otherwise, you can use apache CollectionUtils library to improve performances. Depending on the type of Collection provided, this method will be much faster than calling Collection.containsAll(Collection) instead.
See the doc of apache containsAll here.
int correctCount=0, incorrectCount = 0;
List<String> list1 = new ArrayList<String>(i1.values());
List<String> acct_Rte_Cdes_A = Arrays.asList(result)
for(String tmp1: list1) {
for(String tmp2: list2) {
if(tmp1.compareTo(tmp2) == 0) {
correctCount++;
} else {
incorrectCount++;
}
}
}
it's time complexity is high but it will do the trick.
You can iterate through the lists yourself checking for equality and at the same time keeping a counter to indicate on which position they differ.
Sample (pseudo) code:
//if equal return 0, else position of difference
//keep in mind that item at index [0] is first, so return would be 1 if lists differ there
public int checkEquality(List list1, List list2) {
for (int i = 0; i < list1.size(); ++i) {
if (list1[i] != list2[i])
return i + 1;
}
return 0;
}
Also keep in mind, that you'd have to check if the lists are of the same size, and decide what to do if they are not (for example, return -1 to indicated this).
list1.containsAll(acct_Rte_Cdes_A)
boolean containsAll(Collection<?> c)
Returns true if this list contains all of the elements of the
specified collection.
Related
I have a list of array lists. Each list in the main list contains constant number of items. (Say 3 items in each array list)
. What I want to do is I need to get the indexwise sum of each list as a new List.
for example If my main List contains array lists like
1, 2, 3
1, 2, 3
1, 2, 3
then my resultant list should be
3, 6, 9
and I have to do this with RxJava only. Since I am very new to RxJava I'm confused with wich operators I should use. I tried many ways but since those are not working I'm not posting with question. If anyone could suggest a hint or suggestion it would be very helpful. Thanks in advance
My source list is
List<ArrayList<Integer>> mainList;
and I need a resultant List<Integer> sumList
This is not really the main purpose of RxJava but you can do this via zip:
List<List<Integer>> lists = new ArrayList<>();
for (int i = 0; i < 3; i++) {
lists.add(Arrays.asList(1, 2, 3));
}
Flowable<Integer> f = Flowable.zip(lists, a -> {
int sum = 0;
for (Object o : a) {
sum += (Integer)o;
}
return sum;
})
// as individual items
f.test()
.assertResult(3, 6, 9);
// as one list
f.toList()
.test()
.assertResult(Arrays.asList(3, 6, 9));
1)You should add the following RxMath dependency in your build.gradle (app level).
compile 'io.reactivex:rxjava-math:1.0.0'
2) Use the following code to add sum of integer values from an Array or List.
int totalCount = MathObservable.sumInteger(Observable.just(classesItemList)
.flatMapIterable(new Func1<List<ClassesItem>, Iterable<? extends ClassesItem>>() {
#Override
public Iterable<? extends ClassesItem> call(List<ClassesItem> list) {
return list;
}
})
.map(new Func1<ClassesItem, Integer>() {
#Override
public Integer call(ClassesItem classesItem) {
return classesItem != null ? classesItem.getStudentsCount() : 0;
}
})).toBlocking().single();
3) use the total count wherever you want.
I want to compare two ArrayList of objects and find the unmatching values from the second ArrayList based on the ids in the object.
For Example:
Person.java
private int id;
private String name;
private String place;
MainActivity.java:
ArrayList<Person> arrayList1 = new ArrayList<Person>();
arrayList1.add(new Person(1,"name","place"));
arrayList1.add(new Person(2,"name","place"));
arrayList1.add(new Person(3,"name","place"));
ArrayList<Person> arrayList2 = new ArrayList<Person>();
arrayList2.add(new Person(1,"name","place"));
arrayList2.add(new Person(3,"name","place"));
arrayList2.add(new Person(5,"name","place"));
arrayList2.add(new Person(6,"name","place"));
I want to compare the arrayList1, arrayList2 and need to find the unmatching values from the arrayList2.
I need the id values 5,6.
How can I do this?
You can use an inner loop, to check if the Person's id from arrayList2 corresponds to any Person id in the arrayList1. You'll need a flag to mark if some Person was found.
ArrayList<Integer> results = new ArrayList<>();
// Loop arrayList2 items
for (Person person2 : arrayList2) {
// Loop arrayList1 items
boolean found = false;
for (Person person1 : arrayList1) {
if (person2.id == person1.id) {
found = true;
}
}
if (!found) {
results.add(person2.id);
}
}
Look at the modifications to person class
public static class Person{
//setters and getters
#Override
public boolean equals(Object other) {
if (!(other instanceof Person)) {
return false;
}
Person that = (Person) other;
// Custom equality check here.
return this.getId() == that.getId();
}
}
Have overridden equals(Object other)
then simply do this
for (Person person : arrayList1) {
arrayList2.remove(person);
}
your answer is array list 2, it will only contain odd objects
You should iterate through the shortest ArrayList you have, so check which list is shorter and then iterate through all the indexes in that list against every index in the other list.
(This is assuming you don't have any duplicates in either list. If you do, you might want to return a list of all indexes found.)
arrayListChars=new ArrayList<>(); //[M,A,R,V,E,L]
arrayListAddChars=new ArrayList<>(); //[M,A,....coming values]
int count = 0;
for(int i=0;i
if(arrayListAddChars.get(i).equals(arrayListChars.get(i))){
count++;
}
else
{
break;
}
}
This question already has answers here:
How to remove duplicates from a list?
(15 answers)
Closed 8 years ago.
I want to remove duplicates from ArrayList of type Alerts where Alerts is a class.
Class Alerts -
public class Alerts implements Parcelable {
String date = null;
String alertType = null;
String discription = null;
public Alerts() {
}
public Alerts(String date, String alertType, String discription) {
super();
this.date = date;
this.alertType = alertType;
this.discription = discription;
}
}
Here is how I added the elements -
ArrayList<Alerts> alert = new ArrayList<Alerts>();
Alerts obAlerts = new Alerts();
obAlerts = new Alerts();
obAlerts.date = Date1.toString();
obAlerts.alertType = "Alert Type 1";
obAlerts.discription = "Some Text";
alert.add(obAlerts);
obAlerts = new Alerts();
obAlerts.date = Date2.toString();
obAlerts.alertType = "Alert Type 1";
obAlerts.discription = "Some Text";
alert.add(obAlerts);
What I want to remove from them-
I want all alerts which have unique obAlerts.date and obAlerts.alertType. In other words, remove duplicate obAlerts.date and obAlerts.alertType alerts.
I tried this -
Alerts temp1, temp2;
String macTemp1, macTemp2, macDate1, macDate2;
for(int i=0;i<alert.size();i++)
{
temp1 = alert.get(i);
macTemp1=temp1.alertType.trim();
macDate1 = temp1.date.trim();
for(int j=i+1;j<alert.size();j++)
{
temp2 = alert.get(j);
macTemp2=temp2.alertType.trim();
macDate2 = temp2.date.trim();
if (macTemp2.equals(macTemp1) && macDate1.equals(macDate2))
{
alert.remove(temp2);
}
}
}
I also tried-
HashSet<Alerts> hs = new HashSet<Alerts>();
hs.addAll(obAlerts);
obAlerts.clear();
obAlerts.addAll(hs);
You need to specify yourself how the class decides equality by overriding a pair of methods:
public class Alert {
String date;
String alertType;
#Override
public boolean equals(Object o) {
if (this == 0) {
return true;
}
if ((o == null) || (!(o instanceof Alert)))
return false;
}
Alert alert = (Alert) o;
return this.date.equals(alert.date)
&& this.alertType.equals(alert.alertType);
}
#Override
public int hashCode() {
int dateHash;
int typeHash;
if (date == null) {
dateHash = super.hashCode();
} else {
dateHash = this.date.hashCode();
}
if (alertType == null) {
typeHash = super.hashCode();
} else {
typeHash = this.alertType.hashCode();
}
return dateHash + typeHash;
}
}
You can then loop through your ArrayList and add elements if they aren't already there as Collections.contains() makes use of these methods.
public List<Alert> getUniqueList(List<Alert> alertList) {
List<Alert> uniqueAlerts = new ArrayList<Alert>();
for (Alert alert : alertList) {
if (!uniqueAlerts.contains(alert)) {
uniqueAlerts.add(alert);
}
}
return uniqueAlerts;
}
However, after saying all that, you may want to revisit your design to use a Set or one of its family that doesn't allow duplicate elements. Depends on your project. Here's a comparison of Collections types
You could use a Set<>. By nature, Sets do no include duplicates. You just need to make sure that you have a proper hashCode() and equals() methods.
In your Alerts class, override the hashCode and equals methods to be dependent on the values of the fields you want to be primary keys. Afterwards, you can use a HashSet to store already seen instances while iterating over the ArrayList. When you find an instance which is not in the HashSet, add it to the HashSet, else remove it from the ArrayList. To make your life easier, you could switch to a HashSet altogether and be done with duplicates per se.
Beware that for overriding hashCode and equals, some constraints apply.
This thread has some helpful pointers on how to write good hashCode functions. An important lesson is that simply adding together all dependent fields' hashcodes is not sufficient because then swapping values between fields will lead to identical hashCodes which might not be desirable (compare swapping first name and last name). Instead, some sort of shifting-operation is usually done before adding the next atomic hash, eg. multiplying with a prime.
First store your datas in array then split at as one by one string,, till the length of that data execute arry and compare with acyual data by if condition and retun it,,
HashSet<String> hs = new HashSet<String>();
for(int i=0;i<alert.size();i++)
{
hs.add(alert.get(i).date + ","+ alert.get(i).alertType;
}
alert.clear();
String alertAll[] = null;
for (String s : hs) {
alertAll = s.split(",");
obAlerts = new Alerts();
obAlerts.date = alertAll[0];
obAlerts.alertType = alertAll[1];
alert.add(obAlerts);
}
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 list of integer IDs. Lets say this list is ArrayList<Integer> or int[], it doesn't matter. I have another ArrayList<Obj> that contains the objects with the same ids like in the first list, but they are ordered in different order.
I want to order the objects in the second list in the order as the ids in the first list.
EXAMPLE:
FIRST LIST: { 1, 5, 4, 8, 6 }
SECOND LIST: { Obj[id=5], Obj[id=8], Obj[id=6], Obj[id=1], Obj[id=4] }
RESULT LIST: { Obj[id=1], Obj[id=5], Obj[id=4], Obj[id=8], Obj[id=6] }
Can someone tell me an (efficient) way to do this?
I would suggest using a map:
Map<Integer, Obj> map = new HashMap<Integer, Obj>(secondList.size() * 2);
for (final Obj obj : secondList) {
map.put(obj.id, obj);
}
for (int i = 0; i < secondList.size(); i++) {
secondList.set(i, map.get(firstList.get(i)));
}
This runs in O(n), which IMHO is pretty much the best you can get.
A/ Create a matching id index list, such as:
1 -> 0
5 -> 1
4 -> 2
8 -> 3
6 -> 4
That's a reversed reference of your first list. It indicates the position of each id. A SparseIntArray is a good way of doing it:
SparseIntArray ref = new SparseIntArray();
for (int i = 0; i < firstList.size(); i++) {
ref.append(firstList.get(i), i);
}
Then you need to sort your second list using a Comparator that uses the id of the Object and the ref table:
Collections.sort(secondList, new Comparator<Obj>() {
public int compare(Obj t1, Obj t2) {
return ref.get(t1.id) - ref.get(t2.id);
}
});
I was in the middle of writing Etienne's answer when he posted it, so just for fun here's an O(N^2) solution with a smaller constant factor that doesn't create any objects:
int[] first = { 1, 5, 4, 8, 6 };
Obj[] second = { Obj[id=5], Obj[id=8], Obj[id=6], Obj[id=1], Obj[id=4] };
int i = 0;
while(i < second.length) {
int ind = -1;
for(int j=0;j<first.length;j+=1) {
if(first[j] == second[i].id) {
ind = j;
break;
}
}
if(ind == -1) break; //Bad news
if(ind == i) {
i += 1;
} else {
Obj temp = second[i];
second[i] = second[ind];
second[ind] = temp;
}
}
Obviously the creation of second[] is pseudocode, but the rest will work if the arrays are equal length. I think this will be a little bit faster than Etienne's for very small data sets, but you'd have to profile both answers.