Java:按两列排序多维,并在顶部设置特定行

时间:2018-03-05 14:18:47

标签: java sorting

假设我有这个数组:

[
  ['Chief 1', 'Chief 1'],
  ['Employee 5', 'Chief 2'],
  ['Employee 4', 'Chief 1'],
  ['Employee 2', 'Chief 1'],
  ['Chief 2', 'Chief 2'],
]

我的目标:

[
    ['Chief 1', 'Chief 1'],
    ['Employee 2', 'Chief 1'],
    ['Employee 4', 'Chief 1'],
    ['Chief 2', 'Chief 2'],
    ['Employee 5', 'Chief 2'],
]

我想按照他的负责人对每个员工进行分组,因此我希望根据字母顺序对数组进行排序,并将主管保持在最顶层。
这是我到目前为止所做的,但它仍未按预期工作:

Object[][] data = new Object[2][5];
// after filling the data array
Arrays.sort(data, new Comparator<Object[]>() {
                @Override
                public int compare(Object[] o1, Object[] o2) {
                    String employee1 = (String) o1[0];
                    String employee2 = (String) o2[0];
                    String chief1 = (String) o1[1];
                    String chief2 = (String) o2[1];

                    if(employee1.equals(chief1)){// column 1 equal to column 2 so this is a chief and must stay first
                        return -1;
                    }else{
                        if(chief1.equals(chief2)){// if row 1 equals row 2 so it's the same chief then compare by employe
                            return employee1.compareTo(employee2);
                        }
                        return chief1.compareTo(chief2);// else compare by chief
                    }
                }
            });

这会按字母顺序排序,我不会将数据放在数组的顶部 的修改
这是酋长和员工的一个真实例子:

[
['AMRI Kamel', 'BRAHMI Younes']
['BOULAHMI Fathi', 'BRAHMI Younes']
['BRAHMI Younes', 'BRAHMI Younes']
['ECHI Younes', 'BRAHMI Younes']
['FERCHICHI Khomsi', 'BRAHMI Younes']
['ABDI Hsan ', 'NACEUR Mohamed Ali ']
['BEN MABROUK Houssem', 'NACEUR Mohamed Ali ']
['HARMI Sami', 'NACEUR Mohamed Ali ']
['JBELI Hatem', 'NACEUR Mohamed Ali ']
['JBELI Rached', 'NACEUR Mohamed Ali ']
['LAABIDI Faiek', 'NACEUR Mohamed Ali ']
['LAHBIBI Faouzi', 'NACEUR Mohamed Ali ']
['MLIKI Marouen', 'NACEUR Mohamed Ali ']
['NACEUR Mohamed Ali ', 'NACEUR Mohamed Ali ']
['NEFZI Mustapha', 'NACEUR Mohamed Ali ']
['OUERGHI Sami ', 'NACEUR Mohamed Ali ']
['SASSI Lamjed', 'NACEUR Mohamed Ali ']
['SASSI Mohamed', 'NACEUR Mohamed Ali ']
['ZEDDINI Achref ', 'NACEUR Mohamed Ali ']
['ZOUARI Mohamed Ali ', 'NACEUR Mohamed Ali ']
['ZRIBI  Bilel', 'NACEUR Mohamed Ali ']
]

在这个示例中,我有两个酋长BRAHMI YounesNACEUR Mohamed Ali我的当前代码给了我这个结果,他们按字母顺序排序,但酋长不会显示在他们的员工的顶部。

2 个答案:

答案 0 :(得分:1)

Arrays.sort(data, new Comparator<Object[]>() {
            @Override
            public int compare(Object[] o1, Object[] o2) {
                String employee1 = (String) o1[0];
                String employee2 = (String) o2[0];
                String chief1 = (String) o1[1];
                String chief2 = (String) o2[1];

                if(chief1.equals(chief2))
                    // same chief, sort by empolyee keeping Chief at top
                    if(employee1.equals(chief1))
                        return -1;
                    else if(employee2.equals(chief2))
                        return 1;
                    else
                        return employee1.compareTo(employee2);
                else
                    // if chiefs aren't equals, sort relying on them
                    return chief1.compareTo(chief2);
            }
        });

答案 1 :(得分:1)

基本上,您要做的是排序行和分组 酋长。使用 Java8流可以做得更干净。

假设您定义了一个辅助类Relation来表示每一行:

class Relation implements Comparable<Relation> {
    String chief;        
    String employee;

    public Relation(String[] row) {
        employee = row[0];            
        chief = row[1];
    }

    @Override
    public int compareTo(Relation other) {
        return chief.equals(employee) ? -1 : employee.compareTo(other.employee);        
    }

    @Override
    public String toString() {
        return String.format("[%s, %s]", employee, chief);
    }
}

给定Relation行的列表(称之为relations,让我们说),您可以像这样打印所需的结果:

relations.stream()
    .sorted()
    .collect(Collectors.groupingBy(s -> s.chief))
    .values().stream()
    .flatMap(Collection::stream)
    .forEach(System.out::println);