Сортировать список массивов универсальных объектов Java

Я сделал это некоторое время назад. Не стесняйтесь клонировать и изменять. (Требуются некоторые идеи из старого Vintage Thermometer .)

github.com/Pygmalion69/Gauge

Его можно легко добавить в проект Gradle:

repositories {
    maven {
        url 'https://www.jitpack.io'
    }
}

dependencies {
    compile 'com.github.Pygmalion69:Gauge:1.1'
}

Представления объявлены в XML:


Вот пример программной настройки значений:

    final Gauge gauge1 = (Gauge) findViewById(R.id.gauge1);
    final Gauge gauge2 = (Gauge) findViewById(R.id.gauge2);
    final Gauge gauge3 = (Gauge) findViewById(R.id.gauge3);
    final Gauge gauge4 = (Gauge) findViewById(R.id.gauge4);

    gauge1.moveToValue(800);

    HandlerThread thread = new HandlerThread("GaugeDemoThread");
    thread.start();
    Handler handler = new Handler(thread.getLooper());

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            gauge1.moveToValue(300);
        }
    }, 2800);
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            gauge1.moveToValue(550);
        }
    }, 5600);

    HandlerThread gauge3Thread = new HandlerThread("Gauge3DemoThread");
    gauge3Thread.start();
    Handler gauge3Handler = new Handler(gauge3Thread.getLooper());
    gauge3Handler.post(new Runnable() {
        @Override
        public void run() {
            for (float x = 0; x <= 6; x += .1) {
                float value = (float) Math.atan(x) * 20;
                gauge3.moveToValue(value);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });

    gauge4.setValue(333);

1
задан Jaman 16 January 2019 в 12:43
поделиться

3 ответа

Вопрос в том, знаете ли вы тип элементов в вашей вершине в то время, когда вы хотите провести сравнение.

то есть. этот код действителен из-за стирания типа:

Vertex<String> strVtx = ...
Vertex<Integer> intVtx = ...
List<Vertex> list = Arrays.asList(strVtx, intVtx);
list.sort(aComparer);

Так что реализация компаратора здесь должна быть ненадежной.

Однако, если вы знаете тип, который вы можете просто сделать:

List<Vertex<Integer>> list = ...
list.sort(Comparator.comparing(Vertex::getElement);
0
ответ дан h.alex 16 January 2019 в 12:43
поделиться

Компаратор - хорошая вещь. Он имеет static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor) для этой конкретной проблемы. В вашем случае это было бы

listOfNeighbours.sort(Comparator.comparing(Vertex::getElement))

Если ваш компонент Vertex не Comparable, я бы предложил вместо этого static <T,U> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator) , который можно подавать с помощью специального компаратора. [ 1118]

Например,

import java.util.*;
import javafx.beans.property.*;

public class Vertex<T>{

  private ObjectProperty<T> element;
  private BooleanProperty visited;

  public Vertex() {
      element = null;
      visited = new SimpleBooleanProperty(false);
  }

  public Vertex(T element) {
      this.element = new SimpleObjectProperty<T>(element);
      this.visited = new SimpleBooleanProperty(false);
  }

  public Vertex(T element, boolean visited) {
      this.element = new SimpleObjectProperty<T>(element);
      this.visited = new SimpleBooleanProperty(visited);
  }

  public void setElement(T elem) {
      this.element.set(elem);
  }

  public T getElement() {
      return this.element.get();
  }

  public ObjectProperty<T> elementProperty(){
      return this.element;
  }

  public void setVisited(boolean b) {
      this.visited.set(b);
  }

  public boolean isVisited() {
      return this.visited.get();
  }

  public BooleanProperty visitedProperty(){
      return this.visited;
  }

  @Override
  public boolean equals(Object o) {
      if(o == this) {
          return true;
      }

      if(!(o instanceof Vertex<?>)) {
          return false;
      }

      Vertex<?> v=  (Vertex<?>) o;

      if(v.getElement() instanceof String) {
          return v.getElement().equals(this.element.get());
      }else {
          return v.getElement() == this.element.get();
      }


  }

  @Override
  public String toString() {
      return element.get().toString();
  }

  public static void main(String[] args) {
    ArrayList<Vertex<String>> listOfNeighbours = new ArrayList<>();
    listOfNeighbours.add(new Vertex<>("foo"));
    listOfNeighbours.add(new Vertex<>("bar"));
    System.out.println(listOfNeighbours);
    listOfNeighbours.sort(Comparator.comparing(Vertex::getElement));
    System.out.println(listOfNeighbours);

    ArrayList<Vertex<Integer>> list2 = new ArrayList<>();
    list2.add(new Vertex<>(1));
    list2.add(new Vertex<>(123));
    list2.add(new Vertex<>(15));
    list2.add(new Vertex<>(2));
    System.out.println(list2);
    list2.sort(Comparator.comparing(Vertex::getElement));
    System.out.println(list2);
    list2.sort(Comparator.comparing(Vertex::getElement, Comparator.comparing(i -> i.toString())));
    System.out.println(list2);
  }
}

будет, как это можно сделать (протестировано с https://www.compilejava.net/ ).

Результаты:

[foo, bar]

(исходный ввод)

[bar, foo]

(отсортировано по строке)

[1, 123, 15, 2]

(исходный ввод)

[ 115]

(отсортировано по натуральному целочисленному порядку)

[1, 123, 15, 2]

(отсортировано по порядку, заданному для строки, то есть лексикографически).

Последнее выполняется с помощью Comparator<Vertex<Integer>>, который выполняет свою работу, извлекая значение из заданного Vertex<Integer>, а затем преобразовывая его в String, который затем используется в качестве ключа сортировки.

0
ответ дан glglgl 16 January 2019 в 12:43
поделиться

Если T ограничено Comparable<? super T>, то решение @glglgl, приведенное выше, является достаточно хорошим, так как кажется, что любой из типов, которые T может принять на основании вопроса, является совместимым.

Однако, если T не ограничен таким образом, и вы не можете или не хотите изменить это, решение будет несколько более общим и потребует, чтобы вызывающий код явно предоставил компаратор для [ 115] элементов в качестве второго аргумента для Comparator.comparing

static <T> void sortNeightbours(Collection<Vertex<? extends T>> neighbours, Comparator<? super T> elementComparator) {
    neighbours.sort(Comparator.comparing(Vertex::getElement, elementComparator);
} 

Вам не нужно определять отдельный (статический) метод, для этого он может быть встроен, если хотите.

Для вершины, тип элемента которой сопоставим, как Integer, Double или String, вызывающий код будет таким же:

   List<Vertex<Integer>> ints = ...;
   List<Vertex<Double>> dbls = ...;
   List<Vertex<String>> strs = ...;

   sortNeighbours(ints, Comparator.naturalOrder());
   sortNeighbours(dbls, Comparator.naturalOrder());
   sortNeighbours(strs, Comparator.naturalOrder());

Вы можете определить дополнительный метод для обработки Comparables так, что вам не нужно каждый раз добавлять naturalOrder() вызов в ваш код.

0
ответ дан Valentin Ruano 16 January 2019 в 12:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: