简介
我使用Comparable进行自定义排序的代码并不像我想要的那样工作。我基本上采用一系列目录并按以下方式对它们进行排序:
问题
您输入的示例:
[“/”,“/ usr /”,“/ usr / local /”,“/ usr / local / bin /”,“/ games /”, “/ games / snake /”,“/ homework /”,“/ temp / downloads /”]
哪个应该归还:
[“/”,“/ games /”,“/ homework /”,“/ usr /”,“/ games / snake /”, “/ temp / downloads /”,“/ usr / local /”,“/ usr / local / bin /”]
但由于某些原因,我的代码会返回:
[“/”,“/ usr /”,“/ games /”,“/ homework /”,“/ usr / local /”, “/ games / snake /”,“/ usr / local / bin /”,“/ temp / downloads /”]
我的代码 [已修改评论]
import java.util.*;
public class Dirsort { public String[] sort(String[] dirs) {
//Creates Array list containing Sort object
ArrayList<Sort> mySort = new ArrayList<Sort>();
//Loop that gets the 3 needed values for sorting
for (String d: dirs){
String [] l = d.split("/");//String array for alphabetical comparison
int di = d.length();//Length of array for sorting by number of directories
mySort.add(new Sort(di,l,d));//adds Sort object to arraylist (note d (the entire directory) is needed for the toString)
}
Collections.sort(mySort);//sorts according to compareTo
String [] ans = new String [mySort.size()];//Creates a new string array that will be returned
int count = 0;//to keep track of where we are in the loop for appending
for (Sort s: mySort){
ans[count] = s.toString();
count++;
}
return ans;
}
class Sort implements Comparable<Sort>{
private int d;//number of directories
private String [] arr;//array of strings of names of directories
private String dir;//full directory as string for toString
//Constructor
public Sort(int myD, String [] myArr, String myDir){
d = myD;
arr = myArr;
dir = myDir;
}
//toString
public String toString(){
return dir;
}
@Override
public int compareTo(Sort arg0) {
// TODO Auto-generated method stub
//If they are the same return 0
if (this.equals(arg0)){
return 0;
}
//if the directories are empty
if("/".equals(arg0.dir)){
return 1;
}
if ("/".equals(this.dir)){
return -1;
}
//If they are not the same length the shorter one comes first
if (this.d != arg0.d){
return this.d - arg0.d;
}
//If they are the same length, compare them alphabetically
else{
for (int i = 0; i < arg0.d; i++){
if (!this.arr[i].equals(arg0.arr[i])){
return this.arr[i].compareTo(arg0.arr[i]);
}
}
}
return 0;
}
}
}
答案 0 :(得分:1)
错误在这里:
for (String d: dirs){
String [] l = d.split("/");
int di = d.length(); // <- here
mySort.add(new Sort(di,l,d));
}
因为您要比较整个目录String的长度,而不是目录中“文件夹”的数量。这就是为什么"/usr/"
出现在"/homework/"
之前,例如,因为:
"/usr/".length() == 5
"/homework/".length() == 10
我相信你想要的是这个,使用分割的长度:
int di = l.length;
然后输出是:
/ /games/ /homework/ /usr/ /games/snake/ /temp/downloads/ /usr/local/ /usr/local/bin/
虽然(可能)还有另一个小错误,就是在以分隔符开头的String上调用split会在开头导致一个空字符串。
IE:
"/usr/".split("/") == { "", "usr" }
所以你可能想要做些什么。虽然这里意味着所有这些都以空字符串开头,所以它不会对你进行比较的方式产生影响。
作为旁注,@ JBNizet建议给你的变量更有意义的名字也有帮助。 fullDir.length()
和splitDir.length
会更容易发现(并且可能从未发生过这种情况)。
答案 1 :(得分:0)
这是你的代码的固定版本,它处理两个目录都是"/"
的情况,它删除了部分数组不必要的,错误传递的长度,并使用了更有意义的变量名:
public class Dirsort {
public static void main(String[] args) {
String[] input = new String[] {
"/",
"/usr/",
"/usr/local/",
"/usr/local/bin/",
"/games/",
"/games/snake/",
"/homework/",
"/temp/downloads/"
};
String[] result = new Dirsort().sort(input);
System.out.println("result = " + Arrays.toString(result));
}
public String[] sort(String[] dirs) {
ArrayList<Sort> sorts = new ArrayList<Sort>();
for (String dir : dirs) {
String[] parts = dir.split("/");
sorts.add(new Sort(parts, dir));
}
Collections.sort(sorts);
String[] result = new String[sorts.size()];
int count = 0;
for (Sort sort: sorts) {
result[count] = sort.toString();
count++;
}
return result;
}
class Sort implements Comparable<Sort> {
private String[] parts;
private String dir;
public Sort(String[] parts, String dir) {
this.parts = parts;
this.dir = dir;
}
public String toString(){
return dir;
}
@Override
public int compareTo(Sort other) {
if (this.equals(other)){
return 0;
}
if("/".equals(other.dir) && "/".equals(dir)) {
return 0;
}
if("/".equals(other.dir)){
return 1;
}
if ("/".equals(this.dir)){
return -1;
}
if (this.parts.length != other.parts.length){
return this.parts.length - other.parts.length;
}
else {
for (int i = 0; i < other.parts.length; i++){
if (!this.parts[i].equals(other.parts[i])){
return this.parts[i].compareTo(other.parts[i]);
}
}
}
return 0;
}
}
}
我通过简单地使用我的调试器并使其显示所有变量的值来发现问题。
答案 2 :(得分:0)
public class Disort
{
public static String[] sort(String[] dirs)
{
ArrayList<Path> mySort = new ArrayList<Path>();
Path pathDir;
for(String dir : dirs){
pathDir = Paths.get(dir);
// check if directory exists
if(Files.isDirectory(pathDir)){
mySort.add(pathDir);
}
}
// sort the ArrayList according a personalized comparator
Collections.sort(mySort, new Comparator<Path>(){
@Override
public int compare(Path o1, Path o2)
{
if(o1.getNameCount() < o2.getNameCount()){
return -1;
}
else if(o1.getNameCount() > o2.getNameCount()){
return 1;
}
else{
return o1.compareTo(o2);
}
}
});
// to return a String[] but it will better to return a ArrayList<Path>
String[] result = new String[mySort.size()];
for(int i = 0; i < result.length; i++){
result[i] = mySort.get(i).toString();
}
return result;
}
}