How to compare two arraylist? - java

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;
}
}

Related

Way to return the name with an element in java?

Beginner in Java, I look for the way to return with my function "readPeople ()" the name associated in my ArrayList "this.list" thanks to id given by the user.
Here is my code:
public class PersonneC implements PersonneDB {
this.list = new ArrayList();
People marie = new People(1, "Bower", "Marie");
list.add(marie.toString());
public PeopleWithId readPeople(int idPeople) {
PeopleWithId peoplename = null;
for(int i = 0; i < list.size(); i++) {
if(liste.get(i).equals(idPeople)) {
result = list.get(i);
}
}
return result.getPeopleName(); //ERROR INCOMPATIBLE TYPES
}
Wanted result returned: Bower
Your method returns a string, and the return type of the readPeople is PeopleWithId
ArrayList<People> list = new ArrayList<>();
// add people to the list
People marie = new People(1, "Bower", "Marie");
list.add(marie);
// Search function
public String readPeople(int idPeople) {
People p = null;
for(int i = 0; i < list.size(); i++) {
// If equal than it is the result
if(list.get(i).id == idPeople) {
p = list.get(i);
break;
}
}
return p == null ? null : p.getName();
}
The reason you're getting incompatible types is because in your function readPeople you have told it to return PeopleWithId, where you are returning a string.
After the public modifier change PeopleWithId because this object doesn't exist, change it to a String. What this does is tell the function of the type of object you want to get from it, in this case a String because you're name has been stored as a String.

Sorting a List - How to?

I have three object classes called Size1, Size2, Size3
All Size classes has different values (all Values are Strings):
Size1.getValue() = "1"
Size2.getValue() = "2"
Size3.getValue() = "1"
I want to sort a List so that it wouldn't contain duplicate values.
Here it is what I tried:
private List<Size> getSortedSizes(List<Size> allSizes){
List<Size> sortedArray = new ArrayList<>();
for (int i = 0; i < allSizes.size(); i++){
Size size = allSizes.get(i);
if (sortedArray.size() == 0){
sortedArray.add(Size);
} else {
for (int a = 0; a < sortedArray.size(); a++) {
if (!sortedArray.get(a).getValue().equals(Size.getValue())) {
sortedArray.add(Size);
}
}
}
}
return sortedArray;
}
Add to a TreeSet, not an Arraylist
TreeSets are ordered and cannot contain duplicates
You could implement your method in the following way:
private Set<Size> getSortedSizes(List<Size> allSizes) {
Set<Size> sorted = new TreeSet<>(sortedArray);
return sorted;
}
But you have to implement two methods in your Size class, they are: hashCode() and int compareTo(Object o) from the Comparable interface

Sort ArrayList items by name

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.

Alphanumeric sorting of ArrayList with HashMap

I have an ArrayList with several objects per index. I want to sort this list alphanumerically by one object in particular. The object is "my_id" and the values for this object can look similar to: 1A, 10B, 11B, 2C, 205Z, etc.
I need to sort these to come out: 1A, 2C, 10B, 11B, 205Z. Where the numeric part is sorted first, then the alpha- part is sorted secondary. 1,2,3,4,5,... A,B,C,D,E,...
I checked out some alphanumeric string sorting that worked really well:
http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
Unfortunately I can only get that object to sort and I lose the other objects in my ArrayList as a consequence. I really need a sorting algorithm that can rearrange the ArrayList index's by the object of my choosing and not lose the other objects!
Is there a method to do this already out there? I've been unable to find one. I think it's useful to add that all the objects in my ArrayList are mapped strings: ArrayList<HashMap<String, String>>
[edit]
I have my array:
ArrayList<HashMap<String, String>> al
I then store the object:
String[] alphaNumericStringArray = new String[al.size()];
for(int i = 0; i < al.size(); i++)
{
alphaNumericStringArray[i] = al.get(i).get("my_id");
}
I now sort the string array:
// Sort the array now.
Arrays.sort(alphaNumericStringArray, new AlphanumericSorting());
I then put the object back:
for(int i = 0; i < al.size(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("my_id", alphaNumericStringArray[i]);
// TODO, need to append the rest of the objects.
al.set(i, map);
}
I know what you're thinking, I'm not adding all the objects BACK when I re-map it. This is what I have currently, but what I want is a way to sort the whole list not just the one object "my_id". I want to rearrange the indexes so I don't have to re-map everything at the end.
Running the main method:
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Sorter {
public static void main(String[] args) {
List<String> unsorted = Arrays.asList("1A", "10B", "B", "753c", "Z", "M7", "32x", "11B", "2C", "205Z");
Collections.sort(unsorted, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
if (o1.isEmpty())
return -1;
if (o2.isEmpty())
return 1;
String o1number = extractNumberPrefix(o1);
String o2number = extractNumberPrefix(o2);
if (o1number.isEmpty())
if (o2number.isEmpty())
return o1.compareTo(o2);
else return 1;
if (o2number.isEmpty())
return -1;
if (o1number.equals(o2number))
return o1.compareTo(o2);
return Integer.parseInt(o1number) - Integer.parseInt(o2number);
}
private String extractNumberPrefix(String o1) {
String result = "";
for (int i = 0; i < o1.length(); i++) {
try {
Integer.parseInt(o1.substring(i, i + 1));
result += o1.substring(i, i + 1);
} catch (Exception e) {
break;
}
}
return result;
}
});
System.out.println("sorted = " + unsorted);
}
}
returns:
sorted = [1A, 2C, 10B, 11B, 32x, 205Z, 753c, B, M7, Z]
After careful reconstruction of the Comparator and all the comments I finally figured out how to do this.
Question:
To reiterate what my goal is, as well as the solution. I have an ArrayList<HashMap<String, String>>. I want to sort the ArrayList by one object in the HashMap. My HashMap has more than 1 object in it so I want to retain the entire index of the Array. I also want to sort alphanumerically where numeric values are the first to be sorted, than I sort alphabetically. i.e., 1,2,3,4,... A,B,C,D,...
References:
http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
TL;DR Solution:
In my custom Comparator function public int compare(object firstObj, Object secondObj) I needed to change the String values to HashMap object references/values. Here the KEY_ID is the object that I wanted to sort by. Once I did this I used Collections.sort to sort by the HashMap comparator rather than the Arrays.sort (Collections handles ArrayList/HashMaps).
Code Solution:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
/**
* DOCUMENTATION:
* http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
**/
#SuppressWarnings({"rawtypes", "unchecked"})
public class AlphanumericSorting implements Comparator
{
public int compare(Object firstObjToCompare, Object secondObjToCompare)
{
String firstString = ((HashMap<String,String>) firstObjToCompare).get("KEY_ID");
String secondString = ((HashMap<String,String>) secondObjToCompare).get("KEY_ID");
//String firstString = firstObjToCompare.toString();
//String secondString = secondObjToCompare.toString();
if (secondString == null || firstString == null)
{
return 0;
}
int lengthFirstStr = firstString.length();
int lengthSecondStr = secondString.length();
int index1 = 0;
int index2 = 0;
while(index1 < lengthFirstStr && index2 < lengthSecondStr)
{
char ch1 = firstString.charAt(index1);
char ch2 = secondString.charAt(index2);
char[] space1 = new char[lengthFirstStr];
char[] space2 = new char[lengthSecondStr];
int loc1 = 0;
int loc2 = 0;
do
{
space1[loc1++] = ch1;
index1++;
if (index1 < lengthFirstStr)
{
ch1 = firstString.charAt(index1);
}
else
{
break;
}
}
while (Character.isDigit(ch1) == Character.isDigit(space1[0]));
do
{
space2[loc2++] = ch2;
index2++;
if (index2 < lengthSecondStr)
{
ch2 = secondString.charAt(index2);
} else
{
break;
}
}
while (Character.isDigit(ch2) == Character.isDigit(space2[0]));
String str1 = new String(space1);
String str2 = new String(space2);
int result;
if (Character.isDigit(space1[0]) && Character.isDigit(space2[0]))
{
Integer firstNumberToCompare = new Integer(Integer.parseInt(str1.trim()));
Integer secondNumberToCompare = new Integer(Integer.parseInt(str2.trim()));
result = firstNumberToCompare.compareTo(secondNumberToCompare);
}
else
{
result = str1.compareTo(str2);
}
if (result != 0)
{
return result;
}
}
return lengthFirstStr - lengthSecondStr;
}
/**
* ALPHANUMERIC SORTING
*/
public static ArrayList<HashMap<String, String>> sortArrayList(ArrayList<HashMap<String, String>> al)
{
Collections.sort(al, new AlphanumericSorting());
return al;
}
}
To return the sorted ArrayList:
myArrayList = AlphanumericSorting.sortArrayList(myArrayList);
Where,
ArrayList<HashMap<String, String>> myArrayList;

remove duplicate column values inside a group

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

Categories

Resources