comparing two String Arrays without knowing which one contains more values - java

I have to compare the values of two String Arrays in Java and save the different String.
I already know how to compare String Arrays with the same size.
But the problem is, that the count of values of these String Arrays is unknown in the beginning. So, it's unclear which String Array is larger.
So I have to handle following scenarios:
Scenario 1 (same size and no difference):
String[] test = {Test1, Test2, Test3}
String[] test2 = {Test1, Test2, Test3}
Scenario 2 (same size, but difference):
String[] test = {Test1, Test2, Test3}
String[] test2 = {Test1, Test2, Test4}
Scenario 3 (different size - first String Array contains more values, than second one):
String[] test = {Test1, Test2, Test3}
String[] test2 = {Test1, Test2}
Scenario 4 (different size - second String Array contains more values, than first one):
String[] test = {Test1, Test2}
String[] test2 = {Test1, Test2, Test3}
Implementation Scenario 1:
for(int i = 0; i < test.length; i++){
if(! ( Arrays.asList(test).contains(test2[i]) ) ) {
} else {
System.out.println("Scenario 1");
}
}
Implementation Scenario 2:
ArrayList<String> compare_String = new ArrayList<>();
for(int i = 0; i < test.length; i++){
if(! ( Arrays.asList(test).contains(test2[i]) ) ) {
compare_String.add(test2[i]);
System.out.println("Scenario2");
} else {
System.out.println("Scenario 1");
}
} System.out.println(compare_String);
But how to handle Scenario 3 and 4 if you don't know whether the first String Array contains more elements than the second one, or the second String Array contains more elements than the first one?
Many Thanks.
Update:
thanks a lot for your answers. This works for me:
ArrayList<String> difference = new ArrayList<>();
int j = 0;
if (test > test2) {
try {
for (int i = 0; i < test; i++) {
if (!(Arrays.asList(test2).contains(test1[i]))) {
difference.add(test[i]);
}
j++;
}
} catch (ArrayIndexOutOfBoundsException ar) {
difference.add(test[j]);
}

I have implement compareArrays method to handle your scenario try like following this may solve your problem
public class Test
{
public static void main(String[] args){
compareArrays(new String[]{"Test1", "Test2", "Test3"},new String[]{"Test1", "Test2", "Test3"});
compareArrays(new String[]{"Test1", "Test2", "Test3"},new String[]{"Test1", "Test2", "Test4"});
compareArrays(new String[]{"Test1", "Test2", "Test3"},new String[]{"Test1", "Test2"});
compareArrays(new String[]{"Test1", "Test2"},new String[]{"Test1", "Test2", "Test3"});
}
private static void compareArrays(String[] test,String[] test2){
if(test.length > test2.length){
System.out.println("Scenario 3");
}
else if(test2.length > test.length){
System.out.println("Scenario 4");
}
else {
boolean same = true;
for (int a=0;a<test.length;a++){
if(!test[a].equalsIgnoreCase(test2[a])){
same = false;
}
}
if (same){
System.out.println("Scenario 1");
}
else {
System.out.println("Scenario 2");
}
}
}
}

Use a boolean array to keep track of repeated Strings, and simply check all elements of one array to see if the other contains it. The unused Strings of the second array are also missing on the first, so you can put them on the difference, regardless of array sizes.
String[] array1;
String[] array2;
ArrayList<String> diff = compare_arrays(array1, array2);
public ArrayList<String> compare_arrays(String[] a1, String[] a2){
ArrayList<String> diff = new ArrayList<String>();
boolean[] rep = new boolean[a2.length];
Arrays.fill(a2, false);
for(String str : a1){
if(!Arrays.asList(a2).contains(str)){
diff.add(str);
}
else{
rep[Arrays.asList(a2).indexOf(str)] = true;
}
}
for(int i = 0; i < a2.length; i++){
if(!rep[i]){
diff.add(a2[i]);
}
}
}

Related

Java pairing names from array

So I am trying to create small Java program where names from array are paired. But I don't know how to proceed. I have array with names and the object is to pair two names randomly to make a team. There should be some statement so certain pairs couldn't be made: Miller & James can't be in the same team and no dublicates. How do I do this?
Example output:
James & Hal
import java.util.Random;
public class Teams {
public static void main (String [] args) {
String [] arr = {"John", "James", "George", "Miller", "Hal", "Dan"};
Random random = new Random();
int select = random.nextInt(arr.length);
int selectSecond = random.nextInt(arr.length);
System.out.println(arr[select]);
System.out.println(arr[selectSecond]);
}
}
You can delete the first chosen name from the array and then choose again to get the second one. To delete an element from an array see Removing an element from an Array (Java). Here is one possible implementation (but I didn't test it):
public static void main (String [] args) {
String [] arr = {"John", "James", "George", "Miller", "Hal", "Dan"};
Random random = new Random();
int select = random.nextInt(arr.length);
arr = removeElements(arr, arr[select]);
int selectSecond = random.nextInt(arr.length);
System.out.println(arr[select]);
System.out.println(arr[selectSecond]);
}
// import java.util.LinkedList;
public static String[] removeElements(String[] input, String deleteMe) {
List result = new LinkedList();
for(String item : input)
if(!deleteMe.equals(item))
result.add(item);
return (String[]) result.toArray(input);
}
I would like to use Collections.shuffle instead, and a do while loop like so :
String[] arr = {"John", "James", "George", "Miller", "Hal", "Dan"};
List<String> list = Arrays.asList(arr);
String name1, name2;
do {
Collections.shuffle(list);
name1 = list.get(0);
name2 = list.get(1);
} while ((name2.equals("Miller") && name1.equals("James"))
|| (name1.equals("James") && name2.equals("Miller")));
System.out.println(String.format("%s & %s", name1, name2));
With this solution you don't need to check if the both names are same or not, you just need to check if the two name not equals in the same pair to Miller and James
It will depend which perspective you want to attack here. If you just want to "do the job", you have an extensive list of possibilities (as we already have here), but I would just take care with readability:
public class Teams {
private static String[][] teamsToAvoid = {{"James", "Miller"}, {"John", "Hal"}};
private static String[][] teamsFormed = new String[3][2];
public static void main(String[] args){
String[] names = {"John", "James", "George", "Miller", "Hal", "Dan"};
List<String> namesList = new ArrayList<>(Arrays.asList(names));
Collections.shuffle(namesList);
do {
formTeam(namesList, 0, 1);
} while(namesList != null && !namesList.isEmpty());
for(String[] team : teamsFormed){
System.out.println("Team: {" + team[0] + ", " + team[1] + "}");
}
}
private static void formTeam(List<String> namesList, int firstPlayerIndex, int secondPlayerIndex) {
if(isTeamPossible(namesList.get(firstPlayerIndex), namesList.get(secondPlayerIndex))){
String firstPlayer = namesList.get(firstPlayerIndex);
String secondPlayer = namesList.get(secondPlayerIndex);
teamsFormed[getFormedTeamNextIndex()] = new String[]{firstPlayer, secondPlayer};
namesList.remove(namesList.indexOf(firstPlayer));
namesList.remove(namesList.indexOf(secondPlayer));
} else {
formTeam(namesList, firstPlayerIndex, ++secondPlayerIndex);
}
}
private static boolean isTeamPossible(String player1, String player2) {
for(String[] teamToAvoid : teamsToAvoid){
if(Arrays.asList(teamToAvoid).contains(player1) && Arrays.asList(teamToAvoid).contains(player2)){
return false;
}
}
return true;
}
private static int getFormedTeamNextIndex() {
for(int i = 0; i < teamsFormed.length; i++){
if(teamsFormed[i][0] == null && teamsFormed[i][1] == null)
return i;
}
return 0;
}
}
Doing this you will prevent the same pair in different order and remove those players from the list (preventing their reuse).
I would pay attention when removing from list directly by index also, because when you remove one item the index for items after that one change.

Java substring method giving IndexOutOfBoundsException

I am trying to separate String [] adr = {"Tel Iva +38712345", "Mail Iva ivag#gmail.com", "Tel Ana +12345678"} by looking at each of the element's first word. If the first word is Mail, it goes to String [] m, and if the first word is Tel, it goes to String [] t.
Here is my code:
public static void rep(String a, String []adr) {
int mail=0, tel=0;
for (int i=0; i<adr.length; i++) {
if(adr[i].substring(0, 3).equals("Mail")) {
mail++;
}
else tel++;
}
String [] m = new String [mail];
String [] t = new String [tel];
for(int i=0; i<adr.length; i++) {
if(adr[i].substring(0, 4).equals("Mail")) {
m[i]=adr[i].substring(5);
}
else t[i]=adr[i].substring(4);
System.out.println(adr[i].substring(0, 4));
}
}
But for some reason unknown to me, I get
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: 1
which points at line m[i]=adr[i].substring(5). I really do not understand why. Any help would be appreciated.
Correct Solution. you need to two indices to track m and t array traversal.
public static void rep(String a, String []adr) {
int mail=0, tel=0;
for (int i=0; i<adr.length; i++)
{
if(adr[i].substring(0, 4).equals("Mail")) {
mail++;
}
else tel++;
}
String [] m = new String [mail];
String [] t = new String [tel];
int mIndex =0, tIndex = 0;
for(int i=0; i<adr.length; i++) {
if(adr[i].substring(0, 4).equals("Mail")) {
m[mIndex]=adr[i].substring(4);
mIndex++;
}
else
{
t[tIndex]=adr[i].substring(4);
tIndex++;
}
System.out.println(adr[i].substring(0, 4));
}
}
Well You can try this method, I once coded same type of problem when I was learning Java for the my academics. Well you can also try StringTokenizer method to do the same. Maybe they works better. I am expecting that you are going to insert the whole string not splitted one.
import java.util.*;
import java.lang.*;
import java.*;
public class stringtoken{
public static void main(String args[]){
List<String> m=new ArrayList<String>();
List<String> t=new ArrayList<String>();
String[] s={"Tel Iva +38712345", "Mail Iva ivag#gmail.com", "Tel Ana +12345678"};
for(int i=0;i<s.length;i++){
if(s[i].indexOf("Tel")==0){
t.add(s[i]);
}
else if(s[i].indexOf("Mail")==0){
m.add(s[i]);
}
}
for(int i=0;i<m.size();i++){
System.out.println(m.get(i));
}
for(int i=0;i<t.size();i++){
System.out.println(t.get(i));
}
}
}
Supposedly index you used in the substring method are correct and I will only talk about index of the array :
String [] adr = {"Tel Iva +38712345", "Mail Iva ivag#gmail.com", "Tel Ana +12345678"}
By this data,
mail array's size will be 1, max index can use for mail array is 0
tel array's size will be 2, max index can use for tel array is 1
for(int i=0; i<adr.length; i++) {
if(adr[i].substring(0, 4).equals("Mail")) {
m[i]=adr[i].substring(5);
}
else t[i]=adr[i].substring(4);
System.out.println(adr[i].substring(0, 4));
}
In this loop :
LOOP 1 : i = 0 -> t[0]=xxx; -> OK
LOOP 2 : i = 1 -> m[1]=xxx; -> ERROR, because size of m array is 1, index can only be 0
PS : you need to check the index used in substring method
suppose this sample address array (your parameter adr[])
adr[0] = Maila#a.com
adr[1] = Tele123456
adr[2] = Mailb#a.com
adr[3] = Tele123456
adr[4] = Mailc#a.com
After your first loop which is assign values to int mail and tel
mail = 3;
tel = 2
so your m and t array looks like below.
String [] m = new String [3];
String [] t = new String [2];
What happen is in your last for looping for adr (you parameter array) length which is 5.
and try to assign values to m or t, by index of adr array.
Ex : adr[3] = Tele123456
on your second loop when i = 3 your getting this value and try to assign this value to
t[3] = 123456
where actually t size is 2 and then it occur array out of bound exception.
Hope you understood the issue on your code.
Rather than array for m and t use List.
Consider below example.
public static void rep(String a, String []adr) {
List<String> mails = new ArrayList<>();
List<String> teles = new ArrayList<>();
for (int i=0; i<adr.length; i++) {
if(adr[i].substring(0, 3).equals("Mail")) {
mails.add(adr[i].substring(5));
} else {
mails.add(adr[i].substring(5));
}
}
}
**Note : please fix compile errors if there.

Remove duplicates in 2d array

I want to remove duplicate row in a 2d array . i tried the below code .but it is not working . please help me .
Input :
1,ram,mech
1,ram,mech
2,gopi,csc
2.gopi,civil
output should be :
1,ram,mech
2,gopi,csc
2.gopi,civil
Code :
package employee_dup;
import java.util.*;
public class Employee_dup {
public static void main(String[] args)
{
boolean Switch = true;
System.out.println("Name ID Dept ");
String[][] employee_t = {{"1","ram","Mech"},{"1","siva","Mech"},{"1","gopi","Mech"},{"4","jenkat","Mech"},{"5","linda","Mech"},{"1","velu","Mech"}};
int g = employee_t[0].length;
String[][] array2 = new String[10][g];
int rows = employee_t.length;
Arrays.sort(employee_t, new sort(0));
for(int i=0;i<employee_t.length;i++){
for(int j=0;j<employee_t[0].length;j++){
System.out.print(employee_t[i][j]+" ");
}
System.out.println();
}
List<String[]> l = new ArrayList<String[]>(Arrays.asList(employee_t));
for(int k = 0 ;k < employee_t.length-1;k++)
{
if(employee_t[k][0] == employee_t[k+1][0])
{
System.out.println("same value is present");
l.remove(1);
array2 = l.toArray(new String[][]{});
}
}
System.out.println("Name ID Dept ");
for(int i=0;i<array2.length;i++){
for(int j=0;j<array2[0].length;j++){
System.out.print(array2[i][j]+" ");
}
System.out.println();
}
}
}
class sort implements Comparator {
int j;
sort(int columnToSort) {
this.j = columnToSort;
}
//overriding compare method
public int compare(Object o1, Object o2) {
String[] row1 = (String[]) o1;
String[] row2 = (String[]) o2;
//compare the columns to sort
return row1[j].compareTo(row2[j]);
}
}
First I sorted the array based on column one ,then tried to remove duplicates by checking the first column elements and seconds column elements but it is not removing the required column but remove other columns.
You may give this solution a try:
public static void main(String[] args) {
String[][] employee_t = {
{"1","ram","Mech"},
{"1","ram","Mech"},
{"1","siva","Mech"},
{"1","siva","Mech"},
{"1","gopi","Mech"},
{"1","gopi","Mech"} };
System.out.println("ID Name Dept");
Arrays.stream(employee_t)
.map(Arrays::asList)
.distinct()
.forEach(row -> System.out.printf("%-3s%-7s%s\n", row.get(0), row.get(1), row.get(2)));
}
Output
ID Name Dept
1 ram Mech
1 siva Mech
1 gopi Mech
How it works: comparing arrays does rely on instance equality and not on comparing contained elements by equals. Hence converting each row of your 2D array into a List will enable you to compare lists, which takes equals of the elements contained into account.
The Java Stream API does provide a method distinct which relies on equals and will remove all duplicates for you.
Based on your code. Maybe it is not the BEST solution but it works.
public static void main(String[] args) {
System.out.println("Name ID Dept ");
// I added duplicated rows
String[][] inputArray = {
{ "1", "ram", "Mech" },
{ "1", "siva", "Mech" },
{ "1", "gopi", "Mech" },
{ "1", "gopi", "Mech" },
{ "4", "jenkat", "Mech" },
{ "5", "linda", "Mech" },
{ "1", "velu", "Mech" },
{ "1", "velu", "Mech" }
};
// I will add all rows in a Set as it doesn't store duplicate values
Set<String> solutionSet = new LinkedHashSet<String>();
// I get all rows, create a string and insert into Set
for (int i = 0 ; i < inputArray.length ; i++) {
String input = inputArray[i][0]+","+inputArray[i][1]+","+inputArray[i][2];
solutionSet.add(input);
}
// You know the final size of the output array
String[][] outputArray = new String[solutionSet.size()][3];
// I get the results without duplicated values and reconvert it to your format
int position = 0;
for(String solution : solutionSet) {
String[] solutionArray = solution.split(",");
outputArray[position][0] = solutionArray[0];
outputArray[position][1] = solutionArray[1];
outputArray[position][2] = solutionArray[2];
position++;
}
System.out.println("Name ID Dept ");
for (int i = 0; i < outputArray.length; i++) {
for (int j = 0; j < outputArray[0].length; j++) {
System.out.print(outputArray[i][j] + " ");
}
System.out.println();
}
}
I have posted what I think is a readable and easy to maintain solution.
I decided to use distinct from Stream which is part of Java 8
Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream. - https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#distinct--
Main.class
class Main {
public static void main(String[] args)
{
//Create a list of Employee objects
List<Employee> employeeList = new ArrayList<Employee>();
Employee e1 = new Employee(1, "ram", "mech");
Employee e2 = new Employee(1, "ram", "mech");
Employee e3 = new Employee(2, "gopi", "csc");
Employee e4 = new Employee(2, "gopi", "civil");
employeeList.add(e1);
employeeList.add(e2);
employeeList.add(e3);
employeeList.add(e4);
System.out.println("Before removing duplicates");
employeeList.stream().forEach(System.out::println);
//This is where all the magic happens.
employeeList = employeeList.stream().distinct().collect(Collectors.toList());
System.out.println("\nAfter removing duplicates");
employeeList.stream().forEach(System.out::println);
}
}
Output:
Before removing duplicates
Employee [valA=1, valB=ram, valC=mech]
Employee [valA=1, valB=ram, valC=mech]
Employee [valA=2, valB=gopi, valC=csc]
Employee [valA=2, valB=gopi, valC=civil]
After removing duplicates
Employee [valA=1, valB=ram, valC=mech]
Employee [valA=2, valB=gopi, valC=csc]
Employee [valA=2, valB=gopi, valC=civil]
Employee.class
//This is just a regular POJO class.
class Employee {
int valA;
String valB, valC;
public Employee(int valA, String valB, String valC){
this.valA = valA;
this.valB = valB;
this.valC = valC;
}
public Employee(Employee e) {
this.valA = e.valA;
this.valB = e.valB;
this.valC = e.valC;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + valA;
result = prime * result + ((valB == null) ? 0 : valB.hashCode());
result = prime * result + ((valC == null) ? 0 : valC.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Employee && ((Employee)obj).hashCode() == this.hashCode()){
return true;
}
return false;
}
#Override
public String toString() {
return "Employee [valA=" + valA + ", valB=" + valB + ", valC=" + valC + "]";
}
}
Pre Java - 8 solution. May not be the best way. But a quick solution which works..
String[][] records = {
{"1","ram","Mech"},
{"1","ram","Mech"},
{"1","gopi","csc"},
{"1","gopi","civil"} };
List<String[]> distinctRecordsList = new ArrayList<String[]>();
for(String[] record : records){
if(distinctRecordsList.size()>0){
boolean sameValue = false;
for(String[] distinctRecord : distinctRecordsList){
int distinctRecordFields = distinctRecord.length;
if(record.length==distinctRecordFields){
for(int k=0;k<distinctRecordFields;k++){
sameValue = record[k].equalsIgnoreCase(distinctRecord[k]);
if(!sameValue)
break;
}
}else
throw new Exception("Can't compare the records");
}
if(!sameValue)
distinctRecordsList.add(record);
}else if(distinctRecordsList.size()==0)
distinctRecordsList.add(record);
}
Object[] distRecObjects = distinctRecordsList.toArray();
String[][] distinctRecordsArray = new String[distRecObjects.length][];
int i=0;
for(Object distRecObject : distRecObjects){
distinctRecordsArray[i] = (String[]) distRecObject;
i++;
}
Contrary to some other answers I will try to explain what went wrong in your own code and how to fix it within your code (I agree very much with kkflf that an Employee class would be a huge benefit: it’s more object-oriented and it will help structure the code and give better overview of it).
The issues I see in your code are:
You are not removing the correct element when you detect a duplicate, but always the element at index 1 (the second element since indices count from 0). This isn’t trivial, though, because indices shift as you remove elements. The trick is to iterate backward so only indices that you are finished with shift when you remove an element.
You are using == to compare the first element of the subarrays you are comparing. If you wanted to compare just the first element, you should use equals() for comparison. However, I believe you want to compare the entire row so 2,gopi,csc and 2.gopi,civil are recognized as different and both preserved. Arrays.equals() can do the job.
You need to create array2 only after the loop. As your code stands, if no duplicates are detected, arrays2 is never created.
So your loop becomes:
for (int k = employee_t.length - 1; k >= 1; k--)
{
if (Arrays.equals(employee_t[k], employee_t[k - 1]))
{
System.out.println("same value is present");
l.remove(k);
}
}
array2 = l.toArray(new String[][]{});
This gives you the output you asked for.
Further tips:
Your comparator only compares one field in the inner arrays, which is not enough to guarantee that identical rows come right after each other in the sorted array. You should compare all elements, and also require that the inner arrays have the same length.
Use generics: class Sort extends Comparator<String[]>, and you won’t need the casts in compare()
According to Java naming conventions it should be class EmployeeDup, boolean doSwitch (since switch is a reserved word) and class Sort.
You are not using the variables Switch and rows; delete them.
I have wrote a solution for me. This may not be the best but it works.
public static String[][] removeDuplicate(String[][] matrix) {
String[][] newMatrix = new String[matrix.length][matrix[0].length];
int newMatrixRow = 1;
for (int i = 0; i < matrix[0].length; i++)
newMatrix[0][i] = matrix[0][i];
for (int j = 1; j < matrix.length; j++) {
List<Boolean> list = new ArrayList<>();
for (int i = 0; newMatrix[i][0] != null; i++) {
boolean same = true;
for (int col = 2; col < matrix[j].length; col++) {
if (!newMatrix[i][col].equals(matrix[j][col])) {
same = false;
break;
}
}
list.add(same);
}
if (!list.contains(true)) {
for (int i = 0; i < matrix[j].length; i++) {
newMatrix[newMatrixRow][i] = matrix[j][i];
}
newMatrixRow++;
}
}
int i;
for(i = 0; newMatrix[i][0] != null; i++);
String finalMatrix[][] = new String[i][newMatrix[0].length];
for (i = 0; i < finalMatrix.length; i++) {
for (int j = 0; j < finalMatrix[i].length; j++)
finalMatrix[i][j] = newMatrix[i][j];
}
return finalMatrix;
}
This method will return a matrix without any duplicate rows.

Merging values of 2 string arrays in one concatenated strings array

I have 2 string arrays.
string [] first = {"ajunkbc","ajunkHello","adedbc","abcjunk","add","ad","a","","junk","ajunk","aajunkbb"};
String [] second = {"abc","aHello","adedbc","abcjunk","add","ad","a","","junk","a","aajunkbb"};
I'd like the result of my merge() method to concatenate each element from the first array with the respective element of the second array separated by a comma.
Below is my code
private static String[] merge(String [] tests, String [] expectations){
List<String> testList = Arrays.asList(tests);
List<String> expectationsList = Arrays.asList(expectations);
List<String> retList = new ArrayList<String>();
for(String test : testList){
for(String val : expectationsList){
retList.add(test+","+val);
break;
}
}
This does not work. What's wrong with my code?
What's wrong is that you are looping over expectationsList and breaking out of the loop after the first iteration:
for(String val : expectationsList){
retList.add(test+","+val);
break; //<--- breaking out of loop after first iteration each time
}
So the result is that you are always retrieving the first element of expectationsList.
Since what you want is to loop over two arrays, you should use an index:
for (int i = 0; i < testList.size(); i++) {
retList.add(testList.get(i)+","+expectationsList.get(i));
}
Also, note that this implies that the size of testList is the same as the size of expectationsList. Your method should probably throw an exception if this is not the case.
Note that you do not need to convert the input arrays into lists. You can use them as-is.
private static String[] merge(String[] tests, String[] expectations) {
if (tests.length != expectations.length) {
throw new IllegalArgumentException("input not of same length");
}
String[] result = new String[tests.length];
for (int i = 0; i < tests.length; i++) {
result[i] = tests[i] + "," + expectations[i]);
}
return result;
}
Java 8 solution:
private static String[] merge(String[] tests, String[] expectations) {
if (tests.length != expectations.length) {
throw new IllegalArgumentException("input not of same length");
}
return IntStream.range(0, tests.length).mapToObj(i -> tests[i] + "," + expectations[i]).toArray(String[]::new);
}
You're iterating through each member of testList and then for each one, iterating through each member of expectationsList. You want to iterate through each of both of them together.
What you want to do is something like this:
private static String[] merge(String[] tests, String[] expectations) {
String[] result = new String[tests.length];
for(int i = 0; i < tests.length; i++) {
result[i] = tests[i] + "," + expectations[i];
}
return result;
}
This code makes the assumption that tests and expectations have the same length. You might want to do a check for that at the beginning:
if (tests.length != expectations.length) {
throw new IllegalArgumentException("tests and expectations are of different lengths")
}
Notice how now you're getting the element at the same index from both arrays.
Sidenote: You can iterate over arrays with the for each format. This works just fine:
String[] myStringArray = getStringArray();
for (String myString : myStringArray) {
// Do something
}
You don't need to convert to a List in order to iterate :)

Comparing two rows in a single 2D array

I am trying to compare two rows that are in different order from a 2D array, and store elements that are the same from both rows. Here's an example of what I have produced:
String[] row1 = new String[10];
String[] row2 = new String[10];
String[][] fruit = {{"apple", "banana", "kiwi"},{"kiwi", "oranges", "grapes"}};
for (int i = 0; i < fruit.length; i++ ) {
for (int j = 0; j < fruit[i].length; j++){
if(fruit[0][j].equals(fruit[1][j])) {
row1[j] = fruit[0][j];
row2[j] = fruit[1][j];
System.out.println("Match found");
}else{
System.out.println("Not found");
}
}
}
System.out.println("row1");
System.out.println(Arrays.deepToString(row1));
System.out.println("row2");
System.out.println(Arrays.deepToString(row2));
I want the row1[] and row2[] to store the elements that are the same (which is kiwi in this example). However, the problem is .equals function only detects matching patterns. The example above only prints out nulls from row1 and row2.
It should really print out:
row1
[kiwi]
row2
[kiwi]
Note: I don't want to declare... String check = "kiwi"; because the user can enter anything in the 2D array.
Any suggestions? I feel I am getting close. I saw a similar example of someone using .equals and that worked, but it was only for single arrays.
The limits of your for-loops have been messed up, as well as the array elements that you accessed for comparison. I guess you wanted something like this...
import java.util.Arrays;
public class RowCompare
{
public static void main(String[] args)
{
String[] row1 = new String[10];
String[] row2 = new String[10];
String[][] fruit = {{"apple", "banana", "kiwi"},{"kiwi", "oranges", "grapes"}};
for (int i = 0; i < fruit[0].length; i++ ) {
for (int j = 0; j < fruit[1].length; j++){
if(fruit[0][i].equals(fruit[1][j])) {
row1[i] = fruit[0][i];
row2[j] = fruit[1][j];
System.out.println("Match found");
}else{
System.out.println("Not found");
}
}
}
System.out.println("row1");
System.out.println(Arrays.deepToString(row1));
System.out.println("row2");
System.out.println(Arrays.deepToString(row2));
}
}
But you should probably describe what you want to do with the results. These fixed-size result arrays (String[10]) look dubious, and the currently sketched code can not easily be generalized for MORE than 2 rows. There is probably a MUCH more elegant solution using Sets and Lists ....
You're logic is slightly wrong in your loop.
If you look you are comparing
fruit[0][0].equals(fruit[1][0])
then
fruit[0][1].equals(fruit[1][1])
change if statement to
if(fruit[0][i].equals(fruit[1][j])) {
Your solution is very uneffective since you don't take advantage of the optimization algorythms like hashing:
You should use a HashSet or a HashMap to find fastly if an element is contained.
In addition collections have ready methods like retainAll() to keep only the existing elements (HashSet implements Collection so it's a good candidate for your needs)
retainAll: Retains only the elements in this collection that are contained in the
specified collection (optional operation)
HashSet row1 = new HashSet();
row1.add("Kiwi");
...
HashSet row2 = new HashSet();
row2.add...
System.out.println( row1.retainAll(row2) );
It is less confusing to put the sub-arrays into temporary (1D) arrays: row1Temp and row2Temp.
import java.util.Arrays;
/**
<P>{#code java DoubleArrayXmpl}</P>
**/
public class DoubleArrayXmpl {
public static final void main(String[] igno_red) {
String[] row1Output = new String[10];
String[] row2Output = new String[10];
String[][] fruit = {{"apple", "banana", "kiwi"},{"kiwi", "oranges", "grapes"}};
String[] row1Temp = fruit[0];
String[] row2Temp = fruit[1];
for(int i = 0; i < row1Temp.length; i++) {
for(int j = 0; j < row2Temp.length; j++) {
if(row1Temp[i].equals(row2Temp[j])) {
System.out.println("Match found");
row1Output[i] = row1Temp[i];
row2Output[j] = row2Temp[j];
}else{
System.out.println("Not found");
}
}
}
System.out.println("row1Output");
System.out.println(Arrays.deepToString(row1Output));
System.out.println("row2Output");
System.out.println(Arrays.deepToString(row2Output));
}
}
Output:
[C:\java_code\]java DoubleArrayXmpl
Not found
Not found
Not found
Not found
Not found
Not found
Match found
Not found
Not found
row1Output
[null, null, kiwi, null, null, null, null, null, null, null]
row2Output
[kiwi, null, null, null, null, null, null, null, null, null]
I don't know your requirements, but It's a little odd to put these duplicate values into two different arrays, let alone leaving so many values null. How about using an ArrayList to store a single copy of the matched fruit?
import java.util.Arrays;
/**
<P>{#code java DoubleArrayXmpl}</P>
**/
public class DoubleArrayXmpl {
public static final void main(String[] igno_red) {
ArrayList<String> alMatches = new ArrayList<String>(3);
String[][] fruit = {{"apple", "banana", "kiwi"},{"kiwi", "oranges", "grapes"}};
String[] row1Temp = fruit[0];
String[] row2Temp = fruit[1];
for(int i = 0; i < row1Temp.length; i++) {
for(int j = 0; j < row2Temp.length; j++) {
if(row1Temp[i].equals(row2Temp[j])) {
System.out.println("Match found");
alMatches.add(row1Temp[i]);
}else{
System.out.println("Not found");
}
}
}
System.out.println("All matched fruits:");
for(String s : alMatches) {
System.out.println(s);
}
}
}
Output:
Not found
Not found
Not found
Not found
Not found
Not found
Match found
Not found
Not found
All matched fruits:
kiwi
Or even better, just store the indexes of the matches:
import java.util.Arrays;
import java.util.ArrayList;
/**
<P>{#code java DoubleArrayToMatchedIdxListXmpl}</P>
**/
public class DoubleArrayToMatchedIdxListXmpl {
public static final void main(String[] igno_red) {
ArrayList<Integer> alMatchIdxsInRow1 = new ArrayList<Integer>(3);
String[][] fruit = {{"apple", "banana", "kiwi"},{"kiwi", "oranges", "grapes"}};
String[] row1Temp = fruit[0];
String[] row2Temp = fruit[1];
for(int i = 0; i < row1Temp.length; i++) {
for(int j = 0; j < row2Temp.length; j++) {
if(row1Temp[i].equals(row2Temp[j])) {
System.out.println("Match found");
alMatchIdxsInRow1.add(i);
}else{
System.out.println("Not found");
}
}
}
System.out.println("All matched fruits:");
for(int i : alMatchIdxsInRow1) {
System.out.println(fruit[0][i]);
}
}
}
Output:
Not found
Not found
Not found
Not found
Not found
Not found
Match found
Not found
Not found
All matched fruits:
kiwi

Categories