【问题标题】:Sorting Arraylist created using Generic Class in Java使用 Java 中的泛型类创建的对 Arraylist 进行排序
【发布时间】:2015-03-19 11:16:55
【问题描述】:

我创建了一个名为Pair 的类,它是LR 的泛型类型,基本上可以让我存储对。

我使用Arraylist 来存储Pair 类型,但我不确定如何根据key/value 对arraylist 进行排序(并可能搜索所有元素)并打印ArrayList。

    ArrayList<Pair> a = new ArrayList<Pair>();

    Pair p = new Pair(1,1);
    a.add(p);
    a.add(new Pair(1,3));

    //System.out.println(help please);

下面是Pair

class Pair<L,R> {

        L left;
        R right;

      public Pair(L left, R right) {
        this.left = left;
        this.right = right;
      }

      public L getLeft() { return left; }
      public R getRight() { return right; }

      @Override
      public int hashCode() { return left.hashCode() ^ right.hashCode(); }

      @Override
      public boolean equals(Object o) {
        if (!(o instanceof Pair)) return false;
        Pair pairo = (Pair) o;
        return this.left.equals(pairo.getLeft()) &&
               this.right.equals(pairo.getRight());
      }




    }

【问题讨论】:

  • 声明一个包含原始Pair 实例的ArrayList 会给您带来麻烦吗?你编译了吗?
  • 您在这里使用了大量的原始类型:例如,Pair 而不是 Pair&lt;Integer, Integer&gt;。你真的应该解决这个问题,这样你就有类型安全了。

标签: java generics arraylist


【解决方案1】:

这是一个适用于您的工作代码示例(它使用了一些 Java 8 功能,但如果您受限于较低版本,可以将这些功能换掉)。希望这会有所帮助!

谢谢, 邓肯

package com.hiveit;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Pair<L extends Comparable<L>, R extends Comparable<R>> implements Comparable<Pair<L, R>> {

  L left;
  R right;

  public Pair(final L left, final R right) {
    this.left = left;
    this.right = right;
  }

  public L getLeft() {
    return left;
  }

  public R getRight() {
    return right;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (left == null ? 0 : left.hashCode());
    result = prime * result + (right == null ? 0 : right.hashCode());
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final Pair<?, ?> other = (Pair<?, ?>) obj;
    if (left == null) {
      if (other.left != null) {
        return false;
      }
    } else if (!left.equals(other.left)) {
      return false;
    }
    if (right == null) {
      if (other.right != null) {
        return false;
      }
    } else if (!right.equals(other.right)) {
      return false;
    }
    return true;
  }

  @Override
  public int compareTo(final Pair<L, R> other) {

    final int compareLeft = left.compareTo(other.left);

    if (compareLeft != 0) {
      return compareLeft;
    }

    return right.compareTo(other.right);
  }

  @Override
  public String toString() {
    return "Pair [left=" + left + ", right=" + right + "]";
  }

  public static String listToString(final List<?> list) {
    return list.stream().map((pair) -> {
      return pair.toString();
    }).collect(Collectors.joining(", "));
  }

  public static void main(final String[] args) {

    final List<Pair<Integer, Integer>> a = new ArrayList<>();

    a.add(new Pair<>(1, 1));
    a.add(new Pair<>(2, 1));
    a.add(new Pair<>(2, 3));
    a.add(new Pair<>(1, 2));
    a.add(new Pair<>(1, 3));
    a.add(new Pair<>(2, 2));

    final List<Pair<Integer, Integer>> sortedByKey = new ArrayList<>(a);
    sortedByKey.sort((o1, o2) -> {
      return o1.getLeft().compareTo(o2.getLeft());
    });

    sortedByKey.stream().map((pair) -> {
      return pair.toString();
    }).collect(Collectors.joining(", "));

    final List<Pair<Integer, Integer>> sortedByValue = new ArrayList<>(a);
    sortedByValue.sort((o1, o2) -> {
      return o1.getRight().compareTo(o2.getRight());
    });

    final List<Pair<Integer, Integer>> sortedByKeyAndValue = new ArrayList<>(a);
    sortedByKeyAndValue.sort((o1, o2) -> {
      return o1.compareTo(o2);
    });

    System.out.println("Original                  = " + listToString(a));
    System.out.println("Sorted by Left            = " + listToString(sortedByKey));
    System.out.println("Sorted by Right           = " + listToString(sortedByValue));
    System.out.println("Sorted by Left then Right = " + listToString(sortedByKeyAndValue));

  }
}

【讨论】:

  • 完美。感谢您花时间回答我的问题。真的很感激。
【解决方案2】:

您的Pair 类可以是例如implement Comparator&lt;Pair&gt; 接口。之后你实现方法

@Override
public int compare(Pair o1, Pair o2) {
    // here you need to implement how one Pair can be compared to another
    // in the scope of ordering them
    // you need to fulfil the contract of the Comparator.compare interface
}

【讨论】:

    【解决方案3】:

    Collections API 为此提供了sort 实用程序。

    http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

    您只需要编写一个类来为您的Pair 类实现Comparator

    【讨论】:

      【解决方案4】:

      不要使用你的 Pair 类。如果您需要的是具有泛型类型的已排序、可遍历且高效的键/值对集合,请使用 TreeMap。

      【讨论】:

      • 另外,你的代码不喜欢它编译给我。例如,第一个声明应该是ArrayList&lt;Pair&lt;Integer, Integer&gt; &gt; a = new ArrayList&lt;Pair&lt;Integer, Integer&gt; &gt;();。如果您使用的是 Java 8,也可以使用类型推断。
      • 使用TreeMap 将无法处理多个对具有相同left 值的情况。这不是一回事。
      • 非常真实!但他确实提到了键/值。这个概念本身就是键是唯一的并且指向一个值。所以如果他真的只想要一个元组数组,你是对的,但如果他想要键/值,我会为他指出正确的方向。很难说他对该主题有多熟悉或他的实际问题是什么,但鉴于排序和比较器相当基本(而且他没有想出它们),我认为我提到这一点很好。
      • 树图对我不起作用,因为我需要重复的键值对。
      猜你喜欢
      • 2016-03-01
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      相关资源
      最近更新 更多