我定义了一个比较器CompareUser ,用于比较一个ArrayList,进行对分查找,但报错类转换错误
class CompareUser implements Comparator
{
  public int compare(Object a, Object b)
  {
    User userA=(User)a;//这行还能转换
    User userB=(User)b;//这行就不行了,奇怪!!!
    int id1=Integer.parseInt(userA.getId());
    int id2=Integer.parseInt(userB.getId());
    return id1-id2;
  }
  
}User:
package model;public class User {
  private String id;
  private String name;
  private String birthdate;
  private String address;
  public String getAddress() {
    return address;
  }  public String getBirthdate() {
    return birthdate;
  }  public String getId() {
    return id;
  }  public String getName() {
    return name;
  }  public void setAddress(String address) {
    this.address = address;
  }  public void setBirthdate(String birthdate) {
    this.birthdate = birthdate;
  }  public void setId(String id) {
    this.id = id;
  }  public void setName(String name) {
    this.name = name;
  }
  public String toString()
  {
    return getId()+"\t"+getName()+"\t"+getBirthdate()+"\t"+getAddress();
  }
}

解决方案 »

  1.   

    我拿你的代码运行很正常啊:import java.util.Comparator;public class User {
      public static void main(String[] args) {
        User a = new User();
        a.setId("1");
        User b = new User();
        b.setId("2");
        CompareUser cu = new CompareUser();
        
        System.out.println("ddd == " + cu.compare(a, b));
      }
      private String id;  private String name;  private String birthdate;  private String address;  public String getAddress() {
        return address;
      }  public String getBirthdate() {
        return birthdate;
      }  public String getId() {
        return id;
      }  public String getName() {
        return name;
      }  public void setAddress(String address) {
        this.address = address;
      }  public void setBirthdate(String birthdate) {
        this.birthdate = birthdate;
      }  public void setId(String id) {
        this.id = id;
      }  public void setName(String name) {
        this.name = name;
      }  public String toString() {
        return getId() + "\t" + getName() + "\t" + getBirthdate() + "\t" + getAddress();
      }
    }class CompareUser implements Comparator {
      public int compare(Object a, Object b) {
        User userA = (User)a; 
        User userB = (User)b; 
        int id1 = Integer.parseInt(userA.getId());
        int id2 = Integer.parseInt(userB.getId());
        return id1 - id2;
      }}运行结果:ddd == -1你把错误贴出来看看。
      

  2.   

    package task1;
    /*
    功能:实现学生信息的插入、删除、更新、查询,保存在txt文件里。
    界面:控制台
    */
    import model.User;
    import java.util.*;
    import java.io.*;
    public class Task1Main
    {
      private ArrayList list=new ArrayList();
      private String dbAddr="F:/java/project/jbuilder/task/db/db.txt";//数据文件
      private String maxIdAddr="F:/java/project/jbuilder/task/db/maxid.txt";//当前最大id,用于产生下一个。
      private BufferedReader readConsole=null;//控制台输入流。
      public Task1Main(BufferedReader br)
      {
        readConsole=br;
      }
      public static void main(String[] args) {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        Task1Main task1=new Task1Main(br);
        task1.init();
        String str="";
        while (true)
        {
          task1.showMainMenu();
          boolean extFlag=false;
          try {
            str = br.readLine();
            str=str.trim();
          }
          catch (Exception ex1) {
            ex1.printStackTrace();
          }
          int select = 0;
          try {
            select = Integer.parseInt(str);
          }
          catch (NumberFormatException ex) {
            System.out.println("请输入数值");
            continue;
          }      switch (select)
          {
            case 1:
              User user=task1.collectInsertInfo();
              user.setId(task1.findNextId());
              task1.insert(user);
              task1.showMainMenu();
              break;
            case 2:
              String id=task1.readStr("请输入要删除的ID:");
              task1.deleteById(id);
              task1.showMainMenu();
              break;
            case 3:
              int a;
              String name=task1.readStr("请输入要查询的人名:");
              task1.queryByName(name);
              task1.showMainMenu();
              break;
            case 4:
              user=task1.collectUpdateInfo();
              task1.udpate(user);
              task1.showMainMenu();
              break;
            case 5:
              extFlag=true;
              task1.destroy();
              break;
            default:
              System.out.println("没有输入1--5的数字");
              continue;
          }
          if (extFlag)
          {
            System.out.println("再见!");
            break;
          }
        }
      }
      public void insert(User user)
      {
        list.add(user);
      }   public void udpate(User user)
       {
         int idx=Collections.binarySearch(list,user.getId(),new CompareUser());
         if (idx==-1)
           {
             System.out.println("该记录不存在,无法更新,可能被其他人删除");
             return;
           }
        User userOri=(User)list.get(idx);
        userOri.setName(user.getName());
        userOri.setBirthdate(user.getBirthdate());
        userOri.setAddress(user.getAddress());
       }   public List queryByName(String name)
       {
         ArrayList listRst=null;
         Iterator it=list.iterator();
         while (it.hasNext())
         {
           User userOri=(User)it.next();
           User userRst=new User();
           userRst.setId(userOri.getId());
           userRst.setName(userOri.getName());
           userRst.setBirthdate(userOri.getBirthdate());
           userRst.setAddress(userOri.getAddress());
           listRst.add(userRst);
         }
         return listRst;
       }
        public void deleteById(String id)
       {
        int idx=Collections.binarySearch(list,id,new CompareUser());
        if (idx==-1)
          System.out.println("没有该记录。");
        else
        {
          list.remove(idx);
        }
       }
      public void init()//初始化,将所有数据读取到List里
      {
       try {
       BufferedReader reader=new BufferedReader(new FileReader(dbAddr));
        String line;
        while ((line=reader.readLine())!=null)
        {
          String[] elem=line.split("\t");
          User user=new User();
          user.setId(elem[0]);
          user.setName(elem[1]);
          user.setBirthdate(elem[2]);
          user.setAddress(elem[3]);
          list.add(user);
        }
          reader.close();
        }
        catch (Exception ex) {
          System.out.println("数据文件关闭失败");
          ex.printStackTrace();
        }
      }
      

  3.   

    继续:  public void destroy()//退出时调用,用于将数据写回文件。
      {
        try {
          BufferedWriter writer = new BufferedWriter(new FileWriter(dbAddr));
          Iterator it = list.iterator();
          StringBuffer buffer = new StringBuffer();
          while (it.hasNext()) {
            User user = (User) it.next();
            buffer.append(user);
            buffer.append("\n");
          }
          writer.write(buffer.toString());
          writer.close();
        }
        catch (IOException ex) {
          System.out.println("文件写入失败");
          ex.printStackTrace();
        }
      }
    public User collectInsertInfo()//收集要插入的学生信息
      {
       String name=readStr("请输入名字:");
       String birthDate=readStr("请输入出生日期(格式:1978/10/15):");
       String address=readStr("请输入住址:");
       User user=new User();
       user.setName(name);
       user.setBirthdate(birthDate);
       user.setAddress(address);
       return user;  }
    public String readStr(String msg)//输出提示信息,并收集你的输入。
      {
        System.out.print(msg);
        String rst="";
        try {
          rst = readConsole.readLine();
        }
        catch (IOException ex) {
          ex.printStackTrace();
        }
        finally
        {
          System.out.println();
          return rst;
        }
      }
    public void showMainMenu()//主菜单
      {
        System.out.println("=================================");
        System.out.println("  Main Menu");
        System.out.println("  1.Add a new student");
        System.out.println("  2.Delete a student");
        System.out.println("  3.Query a student information by name");
        System.out.println("  4.Update a student by id");
        System.out.println("  5.Exit");
        System.out.println("=================================");
      }
    private BufferedReader getReader()
      {
        return readConsole;
      }
    private String findNextId()
      {
        String max = null;
        String next="1";
        try {
          File f=new File(maxIdAddr);
          if (f.exists())
          {
            BufferedReader reader = new BufferedReader(new FileReader(f));
            max = reader.readLine();
            if (max == null || max.trim() == "")
              {
                next = "1";
              }
            else
              {
                next = Integer.toString(Integer.parseInt(max) + 1);
              }
          }//不存在
          else
          {
            next="1";
          }
        }
        catch (Exception ex)
        {
          ex.printStackTrace();
        }
        finally
        {
          try {
            FileWriter writer = new FileWriter(new File(maxIdAddr));
            writer.write(next);
            writer.close();
          }
          catch (Exception ex1) {
            System.out.println("写入当前最大ID有错误!");
            ex1.printStackTrace();
          }
          return next;
        }
      }
    public void outputQuery(List aList)//查询
      {
        Iterator it=aList.iterator();
        int cnt=0;
        System.out.println("  ID     姓名     出生日期      住址");
        System.out.println("===================================");
    //    System.out.println("==3======10=======18==========29=====");
        while (it.hasNext())
        {
          User user=(User)it.next();
          System.out.print(addSomeSpace(user.getId(),7));
          System.out.print(addSomeSpace(user.getName(),9));
          System.out.print(addSomeSpace(user.getBirthdate(),12));
          System.out.println(user.getAddress());
          cnt++;
        }
        System.out.println("==============查询到了"+cnt+"条记录=======");
      }
    public static String addSomeSpace(String str,int length)
      {
        byte[] b = null;
        try {
          b = str.getBytes("US-ASCII");
        }
        catch (UnsupportedEncodingException ex) {
          ex.printStackTrace();
        }
        catch(Exception ex)
        {
          ex.printStackTrace();
        }
        StringBuffer buffer=new StringBuffer();
        for (int i = 0; i < length-b.length; i++) {
          buffer.append(" ");
        }
        return str+buffer.toString();
      }
      public User collectUpdateInfo()
        {
         String id=readStr("请输入ID") ;
         String name=readStr("请输入名字:");
         String birthDate=readStr("请输入出生日期(格式:1978/10/15):");
         String address=readStr("请输入住址:");
         User user=new User();
         user.setId(id);
         user.setName(name);
         user.setBirthdate(birthDate);
         user.setAddress(address);
         return user;
        }}
    class CompareUser implements Comparator
    {
      public int compare(Object a, Object b)
      {
        User userA=(User)a;
        User userB=(User)b;
        int id1=Integer.parseInt(userA.getId());
        int id2=Integer.parseInt(userB.getId());
        return id1-id2;  }}User的代码上面有了,不再贴,
      

  4.   

    public int compare(Object a, Object b)
      {
        User userA=(User)a;
        User userB=(User)b;
        int id1=Integer.parseInt(userA.getId());
        int id2=Integer.parseInt(userB.getId());
        return id1-id2;  }
    调试一下上面的方法,不就知道为什么了?
    调试看看a和b的类型是什么,怀疑你调用传递的参数不对
      

  5.   

    按照Acylas的提示,发现a居然是个字符串,就是我要搜索的值。我想搜的是id属性为这个值的User,真奇怪。是我的用法有问题吗?
    int idx=Collections.binarySearch(list,user.getId(),new CompareUser());
                           ^
                                                  |__难道这里要用User对象吗
      

  6.   

    public static int binarySearch(Object[] a,
                                   Object key,
                                   Comparator c)
    可以看出来key和对象数组a中的对象类型应该是一样的,在你的程序中都应该为User, 而对于binarySearch是遍历数组中的每一个元素,与key相比较,比较函数就是你实现的comparable接口,因此public int compare(Object a, Object b) 中第一个元素就是数组中的值,显然他是User类型的,cast没有问题,而第二个值你传入的是User.getID()返回的是String, 显然和User不是同一对象,cast必然会失败!!
      

  7.   

    按照楼上的提示,查找的方法改成如下却报了另一个错:
    public int findIndex(String id)
        {
          User user=new User();
          user.setId(id);
          int idx=Collections.binarySearch(list,user,new CompareUser2());
          return idx;
        }
    要是输入一个存在的id,没错,可以查找到,但随便输入一个不存在的id,就报错:
    java.lang.IndexOutOfBoundsException: Index: -6, Size: 5 at java.util.ArrayList.RangeCheck(ArrayList.java:508) at java.util.ArrayList.remove(ArrayList.java:388) at dao.UserDAOFile.deleteById(UserDAOFile.java:92) at task.BaseConsole.todo(BaseConsole.java:49) at task.TaskMain.main(TaskMain.java:17)
    我输入的是23,不知这是为什么
      

  8.   

    我又写了个简单的测试程序就没有问题:
    package strutstest;
    import java.util.*;
    import java.io.*;
    import java.util.Comparator;
    public class Test implements Serializable {
    public static void main(String[] args) {
    ArrayList list=new ArrayList();
    User u1=new User("111");
        User u2=new User("222");
        User u3=new User("222");
        User u4=new User("222");
        User u5=new User("111");
        User u6=new User("456");
        User u7=new User("14611");
        User u8=new User("1411");
        list.add(u1);
        list.add(u2);
        list.add(u3);
        list.add(u4);
        list.add(u5);
        list.add(u6);
        list.add(u7);
        list.add(u8);User ux=new User("222");
    int rst=Collections.binarySearch(list,ux,new mycom());
    System.out.println(rst);
    原理是一样的,但这个正常,原来程序就报错。我晕
      

  9.   

    终于明白是怎么回事了。未找到返回不一定是-1,有可能是更小的数,这时ArrayList.remove(-2)肯定就有错误了,所以会报:IndexOutOfBoundsException