删除2d数组中的重复项

时间:2017-04-28 11:56:49

标签: java multidimensional-array duplicates

我想删除二维数组中的重复行。我尝试了以下代码。但它无法正常工作。请帮我 。

输入:

1,ram,mech
1,ram,mech
2,gopi,csc
2.gopi,civil
输出应该是:

1,ram,mech
2,gopi,csc
2.gopi,civil

代码:

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

首先,我根据第一列对数组进行了排序,然后尝试通过检查第一列元素和秒列元素来删除重复项,但是它没有删除所需的列,而是删除了其他列。

6 个答案:

答案 0 :(得分:2)

您可以尝试使用此解决方案:

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

<强>输出

ID Name   Dept
1  ram    Mech
1  siva   Mech
1  gopi   Mech

工作原理:比较数组确实依赖于实例相等,而不是equals比较包含的元素。因此,将2D数组的每一行转换为List将使您能够比较列表,其中包含equals个包含的元素。

Java Stream API提供的方法distinct依赖于equals,并会删除所有重复项。

答案 1 :(得分:0)

根据您的代码。也许这不是最佳解决方案,但它确实有效。

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

}

答案 2 :(得分:0)

我已发布了我认为易读且易于维护的解决方案。

我决定使用来自distinct的{​​{1}},这是Java 8的一部分

  

返回由此流的不同元素(根据Object.equals(Object))组成的流。 - https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#distinct--

<强> Main.class

Stream

<强>输出:

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

<强> Employee.class

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]

答案 3 :(得分:0)

Pre Java - 8解决方案。可能不是最好的方式。但是一个有效的快速解决方案..

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

答案 4 :(得分:0)

与其他一些答案相反,我将尝试解释您自己的代码中出现了什么问题,以及如何在代码中修复它(我非常同意kkflf Employee类将是一个巨大的好处:它是更加面向对象,它将有助于构建代码并更好地概述它。)

我在您的代码中看到的问题是:

  • 当您检测到重复时,您没有删除正确的元素,但始终是索引1处的元素(因为索引从0开始计数的第二个元素)。但这并非易事,因为当您删除元素时索引会发生变化。诀窍是迭代向后,这样当你删除元素时,只有你完成的索引才会移位。
  • 您正在使用==来比较您要比较的子阵列的第一个元素。如果您只想比较第一个元素,则应使用equals()进行比较。但是,我相信您要比较整行,因此2,gopi,csc2.gopi,civil被识别为不同并保留。 Arrays.equals()可以完成这项工作。
  • 您只需在循环后创建array2。如您的代码所示,如​​果未检测到重复项,则永远不会创建arrays2

所以你的循环变成了:

    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[][]{});

这为您提供了所要求的输出。

进一步提示:

  • 您的比较器仅比较内部数组中的一个字段,这不足以保证在排序数组中相同的行正好相继出现。您应该比较所有元素,并且还要求内部数组具有相同的长度。
  • 使用泛型:class Sort extends Comparator<String[]>,您不需要compare()
  • 中的演员表
  • 根据Java命名约定,它应该是class EmployeeDupboolean doSwitch(因为switch是保留字)和class Sort
  • 您没有使用变量Switchrows;删除它们。

答案 5 :(得分:0)

我已经为我写了一个解决方案,只是想分享一下,所以我正在写这个答案。这可能不是最好的方法,但是可以。

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

此方法将返回没有重复行的矩阵。 希望这会有所帮助!