【问题标题】:Cannot sort an array list using Collections.sort after implementing Comparable实现 Comparable 后无法使用 Collections.sort 对数组列表进行排序
【发布时间】:2015-10-16 18:15:56
【问题描述】:

正如标题所示,我正在尝试对对象的 ArrayList 进行排序,并且这些对象已经实现了可比较并覆盖了 CompareTo

但是,当我对我的数组列表进行排序时,我得到了这个错误 我似乎无法理解为什么我会遇到这个问题?有人可以帮忙吗?

ItemList 类:

package stories.cs2800;

import java.util.ArrayList;
import java.util.Collections;

import javax.swing.AbstractListModel;

@SuppressWarnings("serial")
public class ItemList extends AbstractListModel<Item> {

  private ArrayList<Item> items;

  /**
   * Constructor that initializes the array list.
   */
  public ItemList() {
    items = new ArrayList<Item>();
  }

  @Override
  public int getSize() {
    return items.size();
  }

  /**
   * Method to get item based on the index.
   * @param argIndex - Takes parameter of type int. 
   * @return  Returns item at the index.
   */
  @Override
  public Item getElementAt(int argIndex) throws IndexOutOfBoundsException {
    if (argIndex < 0 || argIndex >= items.size()) {
      throw new IndexOutOfBoundsException();
    }
    return items.get(argIndex);
  }

  /**
   * Method that gets and Item element based on the name.
   * 
   * @param  argName - takes parameter of type String.
   * @return  Returns the entire item object if name matches, else null.
   */
  public Item getElementByName(String argName) {
    for (Item i : items) {
      if (i.getName().equals(argName)) {
        return i;
      }
    }
    return null;
  }

  /**
   * Method to add another Item into the array list.
   * @param  Takes parameter of type item.
   * @see ArrayList#add
   */
  public void add(Item next) {
    items.add(next);
    Collections.sort(items);
  }

  /**
   * Boolean method to check if list contains the item of type Item.
   * 
   * @param Takes parameter of type item.
   * @return  returns boolean value of true or false if item is contained.
   */
  public Boolean contains(Item argItem) {
    return items.contains(argItem);
  }

  /**
   * Boolean method remove to remove item of type Item from list.
   * 
   * @param Takes parameter of type Item.
   * @return  returns boolean value of true or false if item is removed.
   */
  public Boolean remove(Item argItem) {
    return items.remove(argItem);
  }

  /**
   * Boolean method that removes and item based on its index.
   * 
   * @argIndex  Takes a parameter of type int. 
   * @return returns boolean value of true or false if item was removed based on index.
   */
  public Boolean remove(int argIndex) throws IndexOutOfBoundsException {
    if (argIndex < 0 || argIndex >= items.size()) {
      throw new IndexOutOfBoundsException();
    }
    return items.remove(items.get(argIndex));
  }

  /**
   * Method to find the index of an item object.
   * 
   * @param  Takes parameter of type Item.
   * @return  Returns item index based on the item object entered.
   */
  public int indexOf(Item argItem) {
    return items.indexOf(argItem);
  }

  /**
   * Method to check if item changed.
   * 
   * @param  Takes parameter of type Item.
   */
  public void changed(Item argItem) {
    fireContentsChanged(this, items.indexOf(items), items.indexOf(items));
    /*Method called when one or more items have changed */
  }
}

单项类:

  package stories.cs2800
  public class SingleItem implements Comparable<Item>, Item {

  private String name;
  private float value;
  private Item child;

  /**
   * Constructor for the SingleItem object. 
   *
   * @param argName   Stores the name that is set in constructor
   * @param argValue  Stores the float value that is set in Constructor
   * @param argChild  Stores the value of the child element
  */
  public SingleItem(String argName, float argValue, Item argChild) {
    name = argName;
    value = argValue;
    child = argChild;
  }

  /**
   * Getter method to get the value of the name variable.
   *
   * @return returns the name
   */
  @Override
  public String getName() {
    return this.name;
  }

  /**
   * Getter method to get the value of the Float variable.
   *
   * @return  value set in the value variable
   *
   */
  @Override
  public Float getValue() {
    return this.value;
  }

  /**
   * Setter method to set the value of the Float - No return type.
   * @param argFloat - Takes parameter of type Float using Wrapper class.
   */
  @Override
  public void setValue(Float argFloat) {
    this.value = argFloat;
  }

  /**
   * Method to get the description.
   *
   * @return  Returns the a string with the description
   */
  @Override
  public String getDescription() {
    return "Single items have no description";
  }

  /**
   * Getter method for child element.
   * 
   * @return returns the value of child element
   */
  public Item getChild() {
    return this.child;
  }

  /**
   * Method for adding items.
   * @param child - Takes parameter of type Item.
   * @return  Returns Exception when child is null.
   *
   */

  @Override
  public void add(Item child) {
    if (this.child != null) {
      throw new IllegalStateException();
    }
    this.child = child;
  }

  /**
   * Method for ItemVisitor.
   * @param argVisitor - Takes parameter of ItemVisitor to add current class.
   * @return  Currently no valid method!.
   *
   */
  @Override
  public <T> void accept(ItemVisitor<T> argVisitor) {
    argVisitor.add(this);
  }

  /**
   * Method that takes Boolean as a parameter.
   * @param argBool - Takes parameter of type boolean.
   * @return  Returns exception.
   */
  @Override
  public void open(boolean argBool) throws IllegalStateException {
    throw new IllegalStateException();
  }

  /**
   * Method that compares name to name entered as a parameter.
   * @param item - Takes parameter of type item.
   * @return Returns an int based on comparison of name. E.g. 0 = same, 1 = different.
   */
  @Override
  public int compareTo(Item item) {
    return this.name.compareTo(item.getName());
  }

  /**
   * Method to check if Open.
   * 
   * @return Always returns true.
   */
  @Override
  public boolean isOpen() {
    return true;
  }

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

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    SingleItem other = (SingleItem) obj;
    if (name == null) {
      if (other.name != null) {
        return false;
      }
    } else if (!name.equals(other.name)) {
      return false;
    }
    return true;
  }

  /**
  * toString method to get values of elements.
  * 
  * @return Returns a sentence with the values of all elements.
  */
  @Override
  public String toString() {
    return "Name: " + getName() + ", Value: " + getValue()
        + ", Description: "
        + getDescription();
  }
}

【问题讨论】:

  • 请给我们看代码?
  • 您可能没有在compareTo方法或implements Comparable中使用过项目类型
  • 我在上面添加了我的代码 :) @SacJn
  • 这里看不到 Comparable&lt;Item&gt;
  • 是否每个Item-implementation 都需要实现Compareable?你可以让Item extend Comparable&lt;Item&gt;。如果没有,并且您的 SingleItem 不需要与其他 Item-实现进行比较,请使其实现 Comparable&lt;SingleItem&gt;

标签: java oop arraylist comparable compareto


【解决方案1】:

简而言之,Item 没有实现 Comparable。并且列表是Item的列表。

这里有详细信息。在上面的代码中,items = new ArrayList&lt;Item&gt;();。这意味着编译器只知道在列表项中,类型是 Item。所以当调用Collections.sort(items)时,java编译器发现Item没有实现Comparable。并且会出现如开头所示的错误。

如何解决?更改 Item 的定义,使其实现 Comparable。

如您所见,SingleItem 没有任何内容。因为是impl,items只看到接口Item。

【讨论】:

    猜你喜欢
    • 2018-05-13
    • 2018-05-10
    • 2012-04-22
    • 2017-03-05
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 2016-05-21
    相关资源
    最近更新 更多