i have created an string[] array of row values of a csv file and stored it in array list. i need to group it based on arr[0] and delete any duplicate array values in that group.
there can be n number columns each time. I have taken 3 columns for example
List<String[]> rowList = new ArrayList<String[]>();
BufferedReader reader = null;
reader = new BufferedReader(new FileReader("C:\\test.csv"));
String[] currLineSplitted;
while (reader.ready()) {
currLineSplitted = reader.readLine().split(",");
rowList.add(currLineSplitted);
}
Set<String[]> s = new TreeSet<String[]>(new Comparator<String[]>() {
#Override
public int compare(String[] o1, String[] o2) {
int cmp = 0;
if((o1[0]).compareTo(o2[0])==1){
for(int i=1;i<currLineSplitted.length;i++){
cmp = (o1[i]).compareTo(o2[i]);
}
} else {
cmp=0;
}
return cmp;
}
});
s.addAll(rowList);
List<Object> res = Arrays.asList(s.toArray());
for(Object obj:res){
String[] arr = (String[])obj;
System.out.println(arr[0]+","+arr[1]+","+arr[2]);
}
input file:
{"1","a","gh"}
{"1","a","rs"}
{"1","b","cd"}
{"2","a","xy"}
{"2","b","xy"}
{"3","a","pq"}
output:
1,a,gh
2,b,xy
Required output:
1,a,gh
1,a,rs //should be deleted as in group 1 a is repeated
1,b,cd
2,a,xy
2,b,xy //should be deleted as in group 2 xy is repeated
3,a,pq
You were almost right. I modified your compare function a little. So replace your compare function with this
#Override
public int compare(String[] o1, String[] o2) {
int cmp = 0;
if(o1[0].equals(o2[0])){//grouping 1st column
for(int i=1;i<o1.length;i++){
cmp = (o1[i]).compareTo(o2[i]);
if(cmp==0)
return cmp;// if two column matched return immediately
}
} else {
return o1[0].compareTo(o2[0]);
}
return cmp;
}
Remember there is no guarantee that String.compare will return 1. It compares two strings lexicographically and returns zero if two strings matches.
So in your code following line is creating a logical error.
o1[0]).compareTo(o2[0])==1
Read more about string comparator here
create a class for example ArrayClass
public class ArrayClass{
private String firstItem,secondItem,thirdItem;
public ArrayClass(String[] param){
firstItem = param[0];
secondItem = param[1];
thirdItem = param[2];
}
//getters and setters
}
then override the equals and hashCode method
#Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if (this == obj) return true;
if (obj == null || (this.getClass() != obj.getClass())) {
return false;
}
ArrayClass aC = (ArrayClass) obj;
return (this.firstItem.equals(aC.getFirstItem())
&& this.secondItem.equals(aC.getSecondItem()))
|| (this.firstItem.equals(aC.getFirstItem())
&& this.thirdItem.equals(aC.getThirdItem()));
}
#Override
public int hashCode() {
// TODO Auto-generated method stub
// up to you how you compute your hashcode to be unique
return thirdItem != null ? thirdItem.hashCode() : 0;
}
then in your main class use Set instead of List
Set<ArrayClass> testSet = new HashSet<ArrayClass>();
then modify your while loop
while (reader.ready()) {
ArrayClass aC = new ArrayClass(reader.readLine().split(","));
testSet.add(aC);
}
to show the output
for(ArrayClass aC : testSet){
System.out.println(aC.getFirstItem()+" "+aC.getSecondItem()+" "+aC.getThirdItem());
}
output:
1,a,gh
1,b,cd
2,a,xy
3,a,pq
Related
I have List of objects which has several several members the most important are fullName and isSubscribed. I want sort it alphabetically in the following order:
First show alphabetically ordered objects that isSubscribed flag true.
After that show also alphabetically sorted objects that isSubscribed flag is false.
example of expected Contacts order:
Barry (isSubscribed:true)
Ericsson (isSubscribed:true)
Andy (isSubscribed:false)
Cook (isSubscribed:false)
I call sort method of my list which has overridden method compareTo(). my code is alphabetically ordering properly for flag marked false, however flag marked true is just putting on top of that list without alphabetically order.
example of Contacts order that I have:
Ericsson (isSubscribed:true)
Barry (isSubscribed:true)
Andy (isSubscribed:false)
Cook (isSubscribed:false)
My overridden code of my Comparable Object (I cant use java 8 due to some circumstances(min sdk level), so please dont offer java8 solution):
#Override
public int compareTo(PersonalContact contact) {
String fullName = getFullName() != null ? getFullName() : "";
String contactFullName = contact.getFullName() != null ? contact.getFullName() : "";
int c;
PersonalContact c1 = this;
PersonalContact c2 = contact;
String fullNameContact1 = c1.getFullName();
String fullNameContact2 = c2.getFullName();
Boolean subscribedForPresenceContact1 = c1.isSubscribeForPresenceEnabled();
Boolean subscribedForPresenceContact2 = c2.isSubscribeForPresenceEnabled();
c = subscribedForPresenceContact1.compareTo(subscribedForPresenceContact2);
if (subscribedForPresenceContact1) {
return -1;
} else if (subscribedForPresenceContact2) {
return 1;
} else if (fullName.equals(contactFullName)) {
String id = getAndroidId() != null ? getAndroidId() : "";
String contactId = contact.getAndroidId() != null ? contact.getAndroidId() : "";
if (id.equals(contactId)) {
List<ContactNumberOrAddress> noas1 = getNumbersOrAddresses();
List<ContactNumberOrAddress> noas2 = contact.getNumbersOrAddresses();
if (noas1.size() == noas2.size() && noas1.size() > 0) {
if (!noas1.containsAll(noas2) || !noas2.containsAll(noas1)) {
for (int i = 0; i < noas1.size(); i++) {
int compare = noas1.get(i).compareTo(noas2.get(i));
if (compare != 0) return compare;
}
}
} else {
return Integer.compare(noas1.size(), noas2.size());
}
String org = getOrganization() != null ? getOrganization() : "";
String contactOrg =
contact.getOrganization() != null ? contact.getOrganization() : "";
return org.compareTo(contactOrg);
}
return id.compareTo(contactId);
}
return fullName.compareTo(contactFullName);
}
I would suggest just to use custom comparator for Collections.sort
Like
class PersonalContactComparator implements Comparator<PersonalContact>
{
#Override
public int compare(final PersonalContact o1, final PersonalContact o2)
{
if (o1.isSubscribeForPresenceEnabled() == o2.isSubscribeForPresenceEnabled()) {
return o1.getFullName().compareTo(o2.getFullName());
}
if (o1.isSubscribeForPresenceEnabled()) {
return 1;
}
return -1;
}
}
And use it as Collections.sort(list, new PersonalContactComparator());
PS: This approach is similar to another asnwers, but more general one
If I understood you may use the following:
list.sort(Comparator.comparingInt(pc -> pc.isSubscribeForPresenceEnabled() ? 0 : 1)
.thenComparing(PersonalContact::getFullName));
Or if I am not mistaken (I am not certain atm). Boolean being a Comparable:
list.sort(Comparator.comparing(PersonalContac::isSubscribeForPresenceEnabled)
.reversed()
.thenComparing(PersonalContact::getFullName));
The ~comparing~ methods give a comparison key for any of LHS and RHS, which then can be compared.
Unfortunately there is no comparingBoolean.
There probably a better way, but here my solution
static void sort(final List<PersonalContact> contacts)
{
final List<PersonalContact> subscribed = new ArrayList<>();
final List<PersonalContact> unsubscribed = new ArrayList<>();
for(final PersonalContact contact : contacts)
{
if(contact.isSubscribeForPresenceEnabled())
subscribed.add(contact);
else
unsubscribed.add(contact);
}
final PersonalContactComparator personalContactComparator = new PersonalContactComparator();
subscribed.sort(personalContactComparator);
unsubscribed.sort(personalContactComparator);
contacts.clear();
contacts.addAll(subscribed);
contacts.addAll(unsubscribed);
}
private static class PersonalContactComparator implements Comparator<PersonalContact>
{
#Override
public int compare(final PersonalContact o1, final PersonalContact o2)
{
return o1.getFullName().compareTo(o2.getFullName());
}
}
I am trying to rearrange an ArrayList based on the name of the items to be on specific index.
My list currently is this:
"SL"
"TA"
"VP"
"SP"
"PR"
and i want to rearrange them to:
"SL"
"SP"
"TA"
"PR"
"VP"
but based on the name and not in the index.
I have tried this:
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("SL")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("SP")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("TA")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("PR")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("VP")){
orderedDummyJSONModelList.add(list.get(i));
}
}
and it works fine, but i want to know if there is a more efficient way to do in 1 for loop or maybe a function. I do not wish to do it like this:
orderedDummyJSONModelList.add(list.get(0));
orderedDummyJSONModelList.add(list.get(3));
orderedDummyJSONModelList.add(list.get(1));
orderedDummyJSONModelList.add(list.get(4));
orderedDummyJSONModelList.add(list.get(2));
Which also works. Any ideas?
You can use Collection.Sort method as Collection.Sort(list) since list is a List<String> you will be fine. But if you want to implement a new comparator:
Collections.sort(list, new NameComparator());
class NameComparator implements Comparator<String> { //You can use classes
#Override
public int compare(String a, String b) { //You can use classes
return a.compareTo(b);
}
}
EDIT:
You can define a class comparator for your needs:
class ClassComparator implements Comparator<YourClass> { //You can use classes
#Override
public int compare(YourClass a, YourClass b) { //You can use classes
return a.name.compareTo(b.name);
}
}
The key thing here is: you need to get clear on your requirements.
In other words: of course one can shuffle around objects stored within a list. But: probably you want to do that programmatically.
In other words: the correct approach is to use the built-in Collection sorting mechanisms, but with providing a custom Comparator.
Meaning: you better find an algorithm that defines how to come from
"SL"
"TA"
"VP"
"SP"
"PR"
to
"SL"
"SP"
"TA"
"PR"
"VP"
That algorithm should go into your comparator implementation!
The point is: you have some List<X> in the first place. And X objects provide some sort of method to retrieve those strings you are showing here. Thus you have to create a Comparator<X> that works on X values; and uses some mean to get to those string values; and based on that you decide if X1 is <, = or > than some X2 object!
here´s an answer just specific for your problem working just for the given output. If the List contains anything else this might break your ordering, as there is no rule given on how to order it and the PR just randomly appears in the end.
public static void main(String[] args) {
List<String> justSomeNoRuleOrderingWithARandomPRInside = new ArrayList<String>();
justSomeNoRuleOrderingWithARandomPRInside.add("SL");
justSomeNoRuleOrderingWithARandomPRInside.add("TA");
justSomeNoRuleOrderingWithARandomPRInside.add("VP");
justSomeNoRuleOrderingWithARandomPRInside.add("SP");
justSomeNoRuleOrderingWithARandomPRInside.add("PR");
java.util.Collections.sort(justSomeNoRuleOrderingWithARandomPRInside, new NameComparator());
for(String s : justSomeNoRuleOrderingWithARandomPRInside) {
System.out.println(s);
}
}
static class NameComparator implements Comparator<String> { //You can use classes
#Override
public int compare(String a, String b) { //You can use classes
// Lets just add a T in front to make the VP appear at the end
// after TA, because why not
if (a.equals("PR")) {
a = "T"+a;
} else if(b.equals("PR")) {
b = "T"+b;
}
return a.compareTo(b);
}
}
O/P
SL
SP
TA
PR
VP
But honestly, this solution is crap, and without any clear rule on how to order these this will be doomed to fail as soon as you change anything as #GhostCat tried to explain.
How about this
// define the order
List<String> ORDER = Arrays.asList("SL", "SP", "TA", "PR", "VP");
List<MyObject> list = ...
list.sort((a, b) -> {
// lamba syntax for a Comparator<MyObject>
return Integer.compare(ORDER.indexOf(a.getString()), ORDER.indexOf(b.getString());
});
Note that this will put any strings that aren't defined in the ORDER list at the start of the sorted list. This may or may not be acceptable - it may be worth checking that only valid strings (i.e. members of ORDER) appear as the result of MyObject.getString().
Use a hashmap to store the weight of all strings (Higher the value of the hashmap means the later this string should come in the final list).
Using a Hashmap, so you can expand it later for other strings as well. It'll be easier to enhance in future.
Finally, Use a custom Comparator to do it.
Required Setup:
List<String> listOfStrings = Arrays.asList("SL", "TA", "VP", "SP", "PR");
HashMap<String, Integer> sortOrder = new HashMap<>();
sortOrder.put("SL", 0);
sortOrder.put("TA", 1);
sortOrder.put("VP", 2);
sortOrder.put("SP", 3);
sortOrder.put("PR", 4);
Streams:
List<String> sortedList = listOfStrings.stream().sorted((a, b) -> {
return Integer.compare(sortOrder.get(a), sortOrder.get(b));
}).collect(Collectors.toList());
System.out.println(sortedList);
Non-Stream:
Collections.sort(listOfStrings, (a, b) -> {
return Integer.compare(sortOrder.get(a), sortOrder.get(b));
});
OR
listOfStrings.sort((a, b) -> {
return Integer.compare(sortOrder.get(a), sortOrder.get(b));
});
System.out.println(listOfStrings);
Output:
[SL, TA, VP, SP, PR]
You can build an index map using a LinkedHashMap. This will be used to lookup the order which to sort using the category names of your items.
ItemSorting
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ItemSorting {
public static void main(String[] args) {
List<Item> list = new ArrayList<Item>();
IndexMap indexMap = new IndexMap("SL", "SP", "TA", "PR", "VP");
ItemComparator itemComparator = new ItemComparator(indexMap);
list.add(new Item("SL"));
list.add(new Item("TA"));
list.add(new Item("VP"));
list.add(new Item("SP"));
list.add(new Item("PR"));
Collections.sort(list, itemComparator);
for (Item item : list) {
System.out.println(item);
}
}
}
ItemComparator
import java.util.Comparator;
public class ItemComparator implements Comparator<Item> {
private IndexMap indexMap;
public IndexMap getIndexMap() {
return indexMap;
}
public void setIndexMap(IndexMap indexMap) {
this.indexMap = indexMap;
}
public ItemComparator(IndexMap indexMap) {
this.indexMap = indexMap;
}
#Override
public int compare(Item itemA, Item itemB) {
if (itemB == null) return -1;
if (itemA == null) return 1;
if (itemA.equals(itemB)) return 0;
Integer valA = indexMap.get(itemA.getCategoryName());
Integer valB = indexMap.get(itemB.getCategoryName());
if (valB == null) return -1;
if (valA == null) return 1;
return valA.compareTo(valB);
}
}
IndexMap
import java.util.LinkedHashMap;
public class IndexMap extends LinkedHashMap<String, Integer> {
private static final long serialVersionUID = 7891095847767899453L;
public IndexMap(String... indicies) {
super();
if (indicies != null) {
for (int i = 0; i < indicies.length; i++) {
this.put(indicies[i], new Integer(i));
}
}
}
}
Item
public class Item {
private String categoryName;
public Item(String categoryName) {
super();
this.categoryName = categoryName;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((categoryName == null) ? 0 : categoryName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Item other = (Item) obj;
if (categoryName == null) {
if (other.categoryName != null) return false;
} else if (!categoryName.equals(other.categoryName)) return false;
return true;
}
#Override
public String toString() {
return String.format("Item { \"categoryName\" : \"%s\" }", categoryName);
}
}
Result
Item { "categoryName" : "SL" }
Item { "categoryName" : "SP" }
Item { "categoryName" : "TA" }
Item { "categoryName" : "PR" }
Item { "categoryName" : "VP" }
You coud define a helper method like this one:
public static int get(String name) {
switch (name) {
case "SL":
return 1;
case "SP":
return 2;
case "TA":
return 3;
case "PR":
return 4;
case "VP":
return 5;
default:
return 6;
}
}
and write in your main method something like:
ArrayList<String> al = new ArrayList<>();
al.add("SL");
al.add("TA");
al.add("VP");
al.add("SP");
al.add("PR");
Collections.sort(al, (o1, o2) -> return get(o1) - get(o2); );
al.forEach((s) -> System.out.println(s));
You can create a Map that maintains the position. When you iterate through the unordered list just get the position of that string value and insert into new array(not arraylist), then later if required you can convert that array to ArrayList.
Example code:
Map<String,Integer> map = new HashMap<>(); //you can may be loop through and make this map
map.put("SL", 0);
map.put("SP", 1);
map.put("TA",2);
map.put("PR",3);
map.put("VP",3);
List<String> list1 // your unordered list with values in random order
String[] newArr = new String[list1.size()];
for(String strName: list1){
int position = map.get(strName);
arr[position] = strName;
}
//newArr has ordered result.
I have ArrayList it contains so many arrays, each array contain first name, last name. now I want to sort the list based on the last name.
Example:
ArrayList<String[]> list=new ArrayList<String[]>();
String[] name1={"koti" ,"reddy"};
String[] name2={"hanu" ,"sanjay"};
String[] name3={"ajay" ,"zedeja"};
String[] name4={"basha" ,"kadhar"};
list.add(name1);
list.add(name2);
list.add(name3);
list.add(name4);
I want the sorting order like:
basha kadhar
koti reddy
hanu sanjay
ajay zedeja
Could you please help on this ASAP, Thanks in Advance
Write a custom Comparator and supply that to the appropriate sort overload along with the data.
However, I would recommend a separate Person/Name type, instead of String arrays, as it will make data easier to keep track of and it could implement Comparable (which would eliminate/replace the need of a Comparator).
Now, when writing an applicable compare/compareTo, the code should look similar to:
int cmpLastName = a_lastName.compareTo(b_lastName);
if (cmpLastName == 0) {
// same lastname, order now based on first name
return a_firstName.compareTo(b_firstName);
} else {
// different lastname, so have enough ordering
return cmpLastName;
}
try this
Collections.sort(list, new Comparator<String[]>() {
#Override
public int compare(String[] o1, String[] o2) {
int c = o1[0].compareTo(o2[0]);
if (c != 0) {
return c;
}
return o1[1].compareTo(o2[1]);
}
});
This is how I would perform that sort operation.
public static void main(String[] args) {
ArrayList<String[]> list = new ArrayList<String[]>();
String[] name1 = { "koti", "reddy" };
String[] name2 = { "hanu", "sanjay" };
String[] name3 = { "ajay", "zedeja" };
String[] name4 = { "basha", "kadhar" };
list.add(name1);
list.add(name2);
list.add(name3);
list.add(name4);
System.out.println("Before sorting");
for (String[] r : list) {
System.out.println(Arrays.toString(r));
}
Collections.sort(list, new Comparator<String[]>() {
public int compare(String[] left, String[] right) {
if (left == null) { // null?
if (right == null) { // null == null!
return 0;
}
return -1; // null < not(null)
} else if (right == null) {
return 1; // not(null) > null.
}
// If the last names aren't the same, return the result
// of comparing the last names.
if (left[1].compareTo(right[1]) != 0) {
return left[1].compareTo(right[1]);
}
// Return the result of comparing the first names.
return left[0].compareTo(right[0]);
}
});
System.out.println("After sorting");
for (String[] r : list) {
System.out.println(Arrays.toString(r));
}
}
try this code to achieve your output.
public static void main(String []args){
ArrayList<String[]> list=new ArrayList<String[]>();
String[] name1={"koti" ,"reddy"};
String[] name2={"hanu" ,"sanjay"};
String[] name3={"ajay" ,"zedeja"};
String[] name4={"basha" ,"kadhar"};
list.add(name1);
list.add(name2);
list.add(name3);
list.add(name4);
Collections.sort(list, new Comparator<String[]>() {
#Override
public int compare(String[] s1, String[] s2) {
int i = s1[0].compareTo(s2[0]);
if (i != 0) {
return i;
}
return s1[1].compareTo(s2[1]);
}
});
System.out.println("after sorting"+"\n");
for (String[] s : list) {
for(int i=0;i<s.length;i++){
System.out.print(s[i]+"\t");
}
System.out.print("\n");
}
}
The problem is the following. There are multiple rows that have non-unique identifiers:
id value
0: {1,2,3}
0: {1,2,2}
1: {1,2,3}
2: {1,2,3}
2: {1,1,3}
I have the function equals that can compare multiple rows between each other. I need to write a code that selects the rows as an input of the function equals. The rows selected must have unique ids, BUT I should check all possible combinations of unique ids. For instance, if there are 5 rows with ids: 0,0,1,2,3, then I should check the following two combinations of ids: 0,1,2,3 and 0,1,2,3, because 0 apears twice. Of course, each of these two combinations will consist of unique rows that have id=0.
My code snippet is the following:
public class Test {
public static void main(String[] args) {
ArrayList<Row> allRows = new ArrayList<Row>();
allRows.add(new Row(0,new int[]{1,2,3}));
allRows.add(new Row(0,new int[]{1,2,2}));
allRows.add(new Row(1,new int[]{1,2,3}));
allRows.add(new Row(2,new int[]{1,2,3}));
allRows.add(new Row(2,new int[]{1,1,3}));
boolean answer = hasEqualUniqueRows(allRows);
}
private boolean hasEqualUniqueRows(ArrayList<Row> allTokens) {
for (int i=0; i<allTokens.size(); i++) {
ArrayList<Integer[]> rows = new ArrayList<Integer[]>();
rows = findUniqueRows(i,allTokens);
boolean answer = equalsExceptForNulls(rows);
if (answer) return true;
}
return false;
}
// Compare rows for similarities
public static <T> boolean equalsExceptForNulls(ArrayList<T[]> ts) {
for (int i=0; i<ts.size(); i++) {
for (int j=0; j<ts.size(); j++) {
if (i != j) {
boolean answer = equals(ts.get(i),ts.get(j));
if (!answer) return false;
}
}
}
return true;
}
public static <T> boolean equals(T[] ts1, T[] ts2) {
if (ts1.length != ts2.length) return false;
for(int i = 0; i < ts1.length; i++) {
T t1 = ts1[i], t2 = ts2[i];
if (t1 != null && t2 != null && !t1.equals(t2))
return false;
}
return true;
}
class Row {
private String key;
private Integer[] values;
public Row(String k,Integer[] v) {
this.key = k;
this.values = v;
}
public String getKey() {
return this.key;
}
public Integer[] getValues() {
return this.values;
}
}
}
Since the number of rows with unique ids is apriori unknown, I don´t know how to solve this problem. Any suggestions? Thanks.
Edit#1
I updated the code. Now it´s more complete. But it lacks the implementation of the function findUniqueRows. This function should select rows from the ArrayList that have unique keys (ids). Could someone help me to develop this function? Thanks.
Assuming the objective is to find every combination without duplicates you can do this with the following. The test to find duplicates is just to confirm it doesn't generate any duplicates in the first place.
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String... args) {
Bag<Integer> b = new Bag<>();
b.countFor(1, 2);
b.countFor(2, 1);
b.countFor(3, 3);
Set<String> set = new LinkedHashSet<>();
for (List<Integer> list : b.combinations()) {
System.out.println(list);
String s = list.toString();
if (!set.add(s))
System.err.println("Duplicate entry " + s);
}
}
}
class Bag<E> {
final Map<E, AtomicInteger> countMap = new LinkedHashMap<>();
void countFor(E e, int n) {
countMap.put(e, new AtomicInteger(n));
}
void decrement(E e) {
AtomicInteger ai = countMap.get(e);
if (ai.decrementAndGet() < 1)
countMap.remove(e);
}
void increment(E e) {
AtomicInteger ai = countMap.get(e);
if (ai == null)
countMap.put(e, new AtomicInteger(1));
else
ai.incrementAndGet();
}
List<List<E>> combinations() {
List<List<E>> ret = new ArrayList<>();
List<E> current = new ArrayList<>();
combinations0(ret, current);
return ret;
}
private void combinations0(List<List<E>> ret, List<E> current) {
if (countMap.isEmpty()) {
ret.add(new ArrayList<E>(current));
return;
}
int position = current.size();
current.add(null);
List<E> es = new ArrayList<>(countMap.keySet());
if (es.get(0) instanceof Comparable)
Collections.sort((List) es);
for (E e : es) {
current.set(position, e);
decrement(e);
combinations0(ret, current);
increment(e);
}
current.remove(position);
}
}
I have two ArrayList. Each is of size 100000. I want to compare them and count matched elements.
Here's my code:
for (int i = 0; i < mArryLst2.size(); i++) {
if (ArryLst1.contains(mArryLst2.get(i))) {
matchedPixels++;
}
}
Here comparison process is taking lot of time.
How to solve and optimize this problem.
you should use CollectionUtils.retainAll : Returns a collection containing all the elements in collection1 that are also in collection2.
ArrayList commonList = CollectionUtils.retainAll(list1,list2);
You should transform you first list into a HashSet. HashSet lookups are O(1), and List lookups are O(n). This makes the whole algorithm O(n) rather than O(n^2)
Set<Foo> set1 = new HashSet<Foo>(list1);
for (Foo foo : list2) {
if (set1.contains(foo)) {
matchedPixels++;
}
}
you should look at this link How to compare two Arraylist values in java?. make a copy of one of the list and then call remove all for the list against the other list
List result = new ArrayList(mArryLst2);
result.removeAll(ArryLst1);
You can use
ArrayList Listname = ListUtils.retainAll(list1,list2);
best option is to put all the elements of your 1st ArrayList into a Set(it allows only unique elements).
Now, from ur 2nd ArrayList, add each element to your Set, if the element already exists in your set, then it will return false.
if you have 2 arrayLists ArrayList1 and ArrayList2 and you want all the matches in another ArrayList Diff
HashSet hs = new HashSet();
for(int i : ArrayList1) hs.add(i);
for(int i : ArrayList2)
{
if(!hs.add(i))
Diff.add(i);
}
it will be faster i think
Set set = new HashSet();
set.addAll(ArryLst1);
for (int i = 0; i <mArryLst2.size(); i++)
{
if (set .contains(mArryLst2.get(i)))
{
matchedPixels++;
}
}
There are a couple of ways to speed this up (especially for large arrays) and simplify the code;
// Quick Check to see if the two arrayLists have the same number of elements
if (array1.size() != array2.size())
return false;
// Optionally Sort the arrays - avoid returning false if the elements are the same but
// have been stored out of sequence
Collections.sort(array1);
Collections.sort(array2);
if (array1.hashCode() == array2.hashCode()) {
return true;
} else {
return false;
}
The best way to do is Override equals method and check if each object in your array list is equal or not.
public class CustomClass {
String x;
String a;
String b;
String c;
long l;
#Override
public boolean equals(Object obj) {
return (this.blindlyEquals(obj) && ((CustomClass) obj).blindlyEquals(this));
}
protected boolean blindlyEquals(Object o) {
if (!(o instanceof CustomClass))
return false;
CustomClass p = (CustomClass)o;
return (p.x == this.x && p.a == this.a && p.b == this.b && p.c == this.c && p.l == this.l);
}
}
public class MainClass {
ArrayList<CustomClass> member = new ArrayList<CustomClass>();
ArrayList<CustomClass> server;
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MainClass mainClass = new MainClass();
mainClass.server = mainClass.getServerList();
mainClass.member = mainClass.getLocalList();
if(mainClass.member.equals(mainClass.server)){
System.out.println("true");
//do the needfull, run a for loop to check which object is not equal
}else{
System.out.println("false");
//do the needfull, run a for loop to check which object is not equal
}
}
public ArrayList<CustomClass> getServerList(){
ArrayList<CustomClass> server = new ArrayList<CustomClass>();
CustomClass obj = new CustomClass();
CustomClass obj2 = new CustomClass();
obj.a = "ali";
obj.b = "ball";
obj.c = "cat";
obj.x = "xerox";
obj.l = 10;
obj2.a = "ali";
obj2.b = "ball";
obj2.c = "cat";
obj2.x = "xerox";
obj2.l = 10;
server.add(obj);
server.add(obj2);
return server;
}
public ArrayList<CustomClass> getLocalList(){
ArrayList<CustomClass> memberOne = new ArrayList<CustomClass>();
CustomClass obj = new CustomClass();
CustomClass obj2 = new CustomClass();
obj.a = "ali";
obj.b = "ball";
obj.c = "cat";
obj.x = "xerox";
obj.l = 10;
obj2.a = "ali";
obj2.b = "ball";
obj2.c = "cat";
obj2.x = "xerox";
obj2.l = 10;
memberOne.add(obj);
memberOne.add(obj2);
return memberOne;
}
}