У меня возникли проблемы с вычислением простого метода compareTo для моего класса Page :

  • Страница имеет ссылку на родительскую страницу через getParent () - допускает значение NULL
  • На странице есть переменная order, которая определяет порядок только на том же уровне иерархии.

Мне нравится сортировать следующим образом:

  1. ParentA
  2. SubParentOfA1
  3. SubParentOfA2
  4. РодительB
  5. ParentC
  6. SubParentOfC1
  7. SubParentOfC2

Каким должен быть мой метод compareTo для решения этой проблемы? Я пробовал следующее, которое в настоящее время правильно сортирует только один и тот же уровень.

Мой подход:

@Override
public int compareTo(@NonNull Object o) {
    int compare = 0;
    if (o instanceof Page) {
        Page other = (Page) o;
        if (other.parent != null) {
            compare = this.compareTo(other.parent);
        } else if (parent != null) {
            compare = this.parent.compareTo(other);
        }
        if (compare == 0) {
            compare = Integers.compareTo(this.order, other.order);
        }
    }
    return compare;
}

Изменить: Мой класс страницы:

class Page{
    int order;
    Page parent;
}
3
Frame91 21 Окт 2015 в 09:43

2 ответа

Лучший ответ

Вместо сложных вычислений вы можете просто положиться на цепочку order. Я использовал String для хранения цепочки для каждого «узла»:

class Page implements Comparable<Page> {
    String name;
    int order;
    Page parent;
    String key;

    Page() {
        name = "root";
        order  = 0;
        parent = null;
        key    = "";
    }

    Page(String name, int order, Page parent) {
        this.name   = name;
        this.order  = order;
        this.parent = parent;
        key = parent.key + (char)order;
    }

    @Override
    public int compareTo(Page o) {
        return key.compareTo(o.key);
    }

    @Override
    public String toString() {
        return name;
    }
}

public static void main(String[] args) {
    Page root = new Page();

    Page b    = new Page("b"  , 2, root);
    Page b1   = new Page("b.1", 1, b);
    Page b3   = new Page("b.3", 3, b);
    Page b2   = new Page("b.2", 2, b);

    Page a    = new Page("a"  , 1, root);
    Page a2   = new Page("a.2", 2, a);
    Page a1   = new Page("a.1", 1, a);

    List<Page> pages = Arrays.asList(root, a, a1, a2, b, b1, b2, b3);
    System.out.println(pages);

    Collections.shuffle(pages);
    System.out.println(pages);

    Collections.sort(pages);
    System.out.println(pages);
}

Уловка здесь состоит в том, чтобы использовать String как сортируемый массив short. Массив состоит из order, который формирует путь от корня до узла. root имеет ключ / идентификатор [] и a дочерний элемент от root с order 1 в качестве ключа / идентификатора [1].

Вот матрица ключ / идентификатор:

┌──────┬────────┬───────┬────────────┬─────┐
│ Page │ Parent │ Order │ Parent Key │ Key │
├──────┼────────┼───────┼────────────┼─────┤
│ root │ -      │ -     │ -          │     │
│ a    │ root   │ 1     │            │ 1   │
│ a.1  │ a      │ 1     │ 1          │ 1 1 │
│ a.2  │ a      │ 2     │ 1          │ 1 2 │
│ b    │ root   │ 2     │            │ 2   │
│ b.1  │ b      │ 1     │ 2          │ 2 1 │
│ b.2  │ b      │ 2     │ 2          │ 2 2 │
│ b.3  │ b      │ 3     │ 2          │ 2 3 │
└──────┴────────┴───────┴────────────┴─────┘

Вот пример из другого дерева (ключ в скобках)

root      (     )
├ z       (1    )
│ ├ a     (1 1  )
│ │ └ y   (1 1 1)
│ └ b     (1 2  )
│   └ x   (1 2 1)
└ c       (2    )
  ├ w     (2 1  )
  └ d     (2 2  )
3
LoganMzz 21 Окт 2015 в 21:00

У вас может быть метод определения глубины страницы

Решение такое:

public class Page {
    private int order;
    private Page parent;

    public Page() {
    }

    public Page(int order, Page parent) {
        this.order = order;
        this.parent = parent;
    }

    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public Page getParent() {
        return parent;
    }

    public void setParent(Page parent) {
        this.parent = parent;
    }


    public int compareTo(Object o){
        int compare = 0;
        if (o instanceof Page) {
            Page other = (Page) o;
            if(this.depth() == other.depth()){
                if(Objects.equals(this.getParent(), other.getParent())){
                    return Integer.compare( other.getOrder(),this.getOrder());
                }
                else{
                    return this.getParent().compareTo(other.getParent());
                }
            }
            else{
                return Integer.compare(other.depth() , this.depth());
            }
        }
        return compare;
    }

    public int depth(){
        if(this.parent == null)return 0;
        else return 1+this.parent.depth();
    }

    public static void main(String[] args){
        Page a = new Page(1, null);
        Page a_1 = new Page(1, a);
        Page a_2 = new Page(2, a);
        Page a_1_1 = new Page(1, a_1);
        Page a_1_2 = new Page(2, a_1);
        Page a_2_1 = new Page(1, a_2);
        Page a_2_2 = new Page(2, a_2);

        System.out.println(a_1.compareTo(a_1_1));
        //1 because a_1 has higher depth
        System.out.println(a_1.compareTo(a_2));
        //1 because a_1 has smaller order
        System.out.println(a_1_2.compareTo(a_1_1));
        //-1 because a_1_2 has higher order
        System.out.println(a_2_1.compareTo(a_1_1));
        //-1 because a_2_1 parent is a_2 and a_1_1 parent is a_1
    }
}
3
Aroniaina 21 Окт 2015 в 07:26