HashMap中如何得到keyset的

  看了HashMap的源码后知道是new KeySet(),但是entry中的key是如何被add到这个keyset中的,请大神请教
  public Set<K> keySet() {
        Set<K> ks = keySet;
        return (ks != null ? ks : (keySet = new KeySet()));
    }

    private final class KeySet extends AbstractSet<K> {
        public Iterator<K> iterator() {
            return newKeyIterator();
        }
        public int size() {
            return size;
        }
        public boolean contains(Object o) {
            return containsKey(o);
        }
        public boolean remove(Object o) {
            return HashMap.this.removeEntryForKey(o) != null;
        }
        public void clear() {
            HashMap.this.clear();
        }
    }

回答: HashMap中如何得到keyset的



  1.   KeySet这个类并不是真正意义上的Set集合,它并没有真正实现Set接口的所有函数,只是提供了一个Iterator ,所以他的用处只是用来遍历, 而他的iterator()函数最终却是由KeyIterator来实现,而KeyIterator是对HashMap的HashMapEntry<K, V>[] table来进行迭代遍历的,所以其实说到这看起来 KeySet 本身什么都没做。
      回到开始的一句话 ,KeySet本身不是真正意义上Set集合,不像HashSet有自己的存储变量空间。它的作用主要是用来提供对key的迭代操作。有点像用了代理模式,代理了KeyIterator类 ,当然KeySet也提供了一些其他基本操作,但真正实现都是调用HashMap实现。
      看到这KeySet类就像把对key的操作进行了封装,而具体实现全部由外部实现。
      


    如果我直接就是Set<XXX> set = xxx.keySet();
    那set中有值吗? 
    如果我不调用xxx.keySet().iterator()的情况下

    可能你被KeySet这个名字误导了,他的作用不是用来作为集合存储,而是作为代理来封装对key的操作,这跟是否调用xxx.keySet().iterator()无关,简单来说其实就是个工具类

hashmap 中的Entry链问题

  1. Q
       引用网上的一段话:引用当程序试图将一个key-value对放入HashMap中时,程序首先根据该 key 的 hashCode() 返回值决定该 Entry 的存储位置:如果两个 Entry 的 key 的 hashCode() 返回值相同,那它们的存储位置相同。如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 将覆盖集合中原有 Entry 的 value,但key不会覆盖。如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部

    我的疑问是,这段话要怎么理解
    因为当我定义
    map.put(1,"a");
    map.put(1,"b");
    


    此时map的size实际是1,map.get(1)为b也就是说后put的元素把前面的覆盖了。
    所以我想知道的是这个Entry里有多个元素,该怎么理解?
  2. A
    entry应该指的就是键值对吧

hashmap中的clone为什么是shallow copy of this map

  1. Q
    public Object clone() {
            HashMap<K,V> result = null;
    try {
        result = (HashMap<K,V>)super.clone();
    } catch (CloneNotSupportedException e) {
        // assert false;
    }
            result.table = new Entry[table.length];
            result.entrySet = null;
            result.modCount = 0;
            result.size = 0;
            result.init();
            result.putAllForCreate(this);

            return result;
        }
    新建Entry,把原来Entry中数据放到新的Entry中。新的HashMap与旧的HashMap操作没有关系了,为什么还是shallow?
  2. A
    javadoc上说得很清楚呀
    引用
        /**
         * Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and
         * values themselves are not cloned.

         *
         * @return a shallow copy of this map
         */

如何使用struts2的标签迭代出HashMap中的List的记录?

  1. Q
    我Action中有一个HashMap,里面存放的是以ID为key,List为value的数据,请问怎样才能使用struts2的标签迭代出里面的数据?
    我目前是这样写的:
    <s:iterator value="answerHashMap">
           <s:iterator value="<s:property value="subjectId"/>">
                  <s:property value="answerContent"/><br>
           </s:iterator>
    </s:iterator>
    


    weblogic控制台报出异常:
    weblogic.servlet.jsp.JspException: (line 124): Non-matching extension tags //[ null; Line: 124]

    问题补充:
    xuxiaolei (中级程序员):

    我要想区HashMap里面的指定key的value呢?
  2. A
    我要想区HashMap里面的指定key的value呢
    取hashMap指定key的value用hashMap['list']

    然后迭代value值用下面的语句
    <ww:iterator value="hashMap['list']">
        <ww:property /> <BR>
    </ww:iterator>

用java多线程统计超大数据文件(1TB以上)中出现次数最多的人名

  1. Q
    各位亲,现在有一个需求是:
    如何在一台多核服务器上快速的统计一个超大的数据文件(1TB以上)中出现次数最多的人名。文件内容格式如下:
    张三
    李四
    王五
    赵六
    ...........

    要求用java多线程实现。
    ps:之前用hashcode取模的方式实现了,但是效果不是太理想,想换成多线程处理,求高人指点。
  2. A
    CountWordsThread.java

    public class CountWordsThread implements Runnable{
    private FileChannel fileChannel = null;
    private FileLock lock = null;
    private MappedByteBuffer mbBuf = null;
    private Map<String, Integer> hashMap = null;

    public CountWordsThread(File file, long start, long end) {
    try {
    // 得到当前文件的通道
    fileChannel = new RandomAccessFile(file, "rw").getChannel();
    // 锁定当前文件的部分
    lock = fileChannel.lock(start, end, false);
    // 对当前文件片段建立内存映射,如果文件过大需要切割成多个片段
    mbBuf = fileChannel.map(FileChannel.MapMode.READ_ONLY, start, end);
    // 创建HashMap实例存放处理结果
    hashMap = new HashMap<String,Integer>();
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    @Override
    public void run() {
    String str = Charset.forName("UTF-8").decode(mbBuf).toString();
    StringTokenizer token = new StringTokenizer(str);
    String word = null;
    while(token.hasMoreTokens()) {
    // 将处理结果放到一个HashMap中
    word = token.nextToken().toString().trim();
    if(null != hashMap.get(word)) {
    hashMap.put(word, hashMap.get(word) + 1);
    } else {
    hashMap.put(word, 1);
    }
    }
    try {
    // 释放文件锁
    lock.release();
    // 关闭文件通道
    fileChannel.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    return;
    }

    //获取当前线程的执行结果
    public Map<String, Integer> getResultMap() {
    return hashMap;
    }
    }

    DealFileText.java

    public class DealFileText {

    // 要处理的文件
    private File file = null;

    // 线程数数组
    private CountWordsThread[] threads = null;

    private List<Thread> listThread = null;

    public DealFileText(File file){
    this.file = file;
    }

    public DealFileText(File file , int threadNum){
    this.file = file;
    this.threads = new CountWordsThread[threadNum];
    }

    public void dealFile(){
    final CountWordsThread thread1 = new CountWordsThread(file, 0, file.length()/2);
    final CountWordsThread thread2 = new CountWordsThread(file, file.length()/2, file.length());
    final Thread t1 = new Thread(thread1);
    final Thread t2 = new Thread(thread2);
    // 开启两个线程分别处理文件的不同片段
    t1.start();
    t2.start();
    Thread mainThread = new Thread() {
    public void run() {
    while(true) {
    // 两个线程均运行结束
    if(Thread.State.TERMINATED == t1.getState() && Thread.State.TERMINATED == t2.getState()) {
    // 获取各自处理的结果
    Map<String, Integer> hMap1 = thread1.getResultMap();
    Map<String, Integer> hMap2 = thread2.getResultMap();

    // 使用TreeMap保证结果有序
    TreeMap<String, Integer> tMap = new TreeMap<String, Integer>();
    // 对不同线程处理的结果进行整合
    tMap.putAll(hMap1);
    tMap.putAll(hMap2);

    Map<String, Integer> map = maxCountOfCharacters(tMap);
    showMessage(map);

    t1.interrupt();
    t2.interrupt();
        return;
    }
    }
    }
    };
    mainThread.start();
    }

    public void createThreads(){
    listThread = new ArrayList<Thread>();
    // 每线程应该读取的字节数
    long numPerThred = this.file.length() / this.threads.length;
    // 整个文件整除后剩下的余数
    long left = this.file.length() % this.threads.length;
    Thread  tempThread = null;
    for (int i = 0; i < this.threads.length; i++) {
    // 让每个线程分别负责读取文件的不同部分。
    try {
    // 最后一个线程读取指定numPerThred+left个字节
    if (i == this.threads.length - 1) {
    this.threads[i] = new CountWordsThread(file,i * numPerThred, (i + 1)
    * numPerThred + left);
    } else {// 每个线程负责读取一定的numPerThred个字节
    this.threads[i] = new CountWordsThread(file,i * numPerThred, (i + 1)
    * numPerThred );
    }
    tempThread = new Thread(threads[i]);
    tempThread.start();
    listThread.add(tempThread);
    } catch (Exception e) {
    System.out.println("系统出现严重错误!系统将终止运行!");
    e.printStackTrace();
    System.exit(-1);// 系统退出
    }
    }
    }


    public void doResult(){
    if(null != listThread && listThread.size() > 0){
    for(int i=0;i<listThread.size(); i++){

    }
    }
    }

    public List<CountWordsThread> doThread(CountWordsThread thread){
    List<CountWordsThread> list = new ArrayList<CountWordsThread>();
    list.add(thread);
    return list;


    public static Map<String, Integer> maxCountOfCharacters(Map<String, Integer> chineseCounts) {
    if (chineseCounts == null) {
    return null;
    }
    Set<String> keys = chineseCounts.keySet();
    Iterator<String> iterator = keys.iterator();
    int max = 0;
    Map<String, Integer> result = new HashMap<String, Integer>();
    while (iterator.hasNext()) {
    String currChar = iterator.next();
    int currCount = chineseCounts.get(currChar);
    if (currCount > max) {
    max = currCount;
    result.clear();
    result.put(currChar, max);
    } else if (currCount == max) {
    result.put(currChar, max);
    }
    }
    return result;
    }

    public static void showMessage(Map<String, Integer> map){
    if(null != map && map.size() > 0){
    Set<String> keys = map.keySet();
    Iterator<String> iterator = keys.iterator();
    while (iterator.hasNext()) {
    String key = (String) iterator.next();
    System.out.println("出现次数最多的人是【 " + key + "】" + "  次数为:【" + map.get(key) + "】");
    }
    }
    }
    }


    简单写了一下,楼主自己研究一下吧。

从数组中删除重复的元素,并考虑算法的执行效率

  1. Q
    写一个函数来从数组中删除重复的对象。维持秩序。例如,如果输入的数组[ 1,5,4,2,7,2,6,5 ],结果应该是[ 1,5,4,2,7,6 ]。实施时应执行速度的优化。
  2. A
    最快的算法肯定是O(n)
    具体做法是:
    1,准备一个HashMap或者HashTable
    2,循环你的输入数组,判断他是否在HashMap中,如果不是,输出,并且加入到HashMap中(比如:Map.put(1,true)),如果是在HashMap中则什么都不做。

    因为HashMap的读取和设置是O(1)的时间复杂度,所以加上循环整体的时间复杂度也是O(n)

关于HashMap的put问题

  1. Q
    Map map = new HashMap();
    map.put("1",new Object());
    上面是把new出来的一个对象作为“值”放入了map中。

    可是下面的就不理解了:
    Object a = new Object();
    map.put("1",a);
    想问下放入map的到底是new出来的对象的引用(即:a),还是这个对象本身呢?
    求解!多谢!
    问题补充:stormtoy 写道对象的引用地址


    两种方式存储的都是对象的内存地址吗?
    可是我做了一个测试:
      byte a[] = new byte[1024*1024*30];   //大小30M
    然后把a放入了map,整个程序才循环了7次就报内存溢出的错误了。
    如果只是存放的对象的内存地址的话,不应该只能存放7个地址吧&


    问题补充:stormtoy 写道我想是因为你运行程序的jvm内存小于你使用的内存,所以出现内存溢出。你应该区分一下值传递和引用传递,值传递是拷贝一个副本到方法里,你方法里面怎么改不会影响到外边,引用传递传递的时对象的地址,调用方法外和内操纵都是同一份地址,所以这个对象改变了,将会影响到外面(因为你外面那个变量指向了这个对象)。




    那这两种方法到底有没有区别呢?是不是前者存在map里面的是对象,后这存入map的是对象的引用地址?
  2. A
    1.hashMap存储的都是地址:
    public class TShashMap {
    	public static void main(String[] args) {
    		Map ts = new HashMap();
    		TSA tsa = new TSA();
    		tsa.setAge(15);
    		tsa.setName("hashMap");
    		ts.put(1, tsa);
    		System.out.println((TSA)ts.get(1));
    		tsa.setAge(18);
    
    		System.out.println((TSA)ts.get(1));
    	}
    }
    class TSA {
    	private String name;
    	private int age;
    	
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String toString() {
    		return "name:" + name + " age:" + age;
    	}
    }
    

    楼主跑下上面的i.e就明白了
    2.你给的i.e,内存溢出是由于java虚拟机本身的原因,和内存没有关系。
    只要存入hashmap中的元素在1<<30之内,就OK

hashmap查找与hashcode

  1. Q
    Map map=new HashMap();
    String s1=new String("AA");
    String s3=new String("AA");
    String s4="AA";
    String s6="AA";
    map.put(s1,"Value");
    String s2=(String)map.get(s3);
    String s5=(String)map.get(s4);
    s1==s3 false   s4==s6 true //这里的==比较的应该不是hashcode吧
    s2,s5都可以得到值Value

    这里以下是查找key是否存在Entry[] table中
    if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
    1: hashcode的API上解释是 将该对象的内部地址转换成一个整数来实现的。这里的内部地址是该对象在堆中的地址还是对象的引用存储在栈中的地址计算出来的?
    2: java中可以输出一个对象在堆中的地址吗?在同一个JVM进程中是否有可能不同的对象的引用输出相同的hashcode呢?
    3:为什么s1,s3,s4的hashcode都是相同的在我机子上是2080。不是说s1,s3的引用是指向堆中的对象的实例吗?s4是方法区中得字符串常量池?这里的hashcode是引用本身存储在栈中的地址呢还是其指向的对象在堆中的地址?
    4 :s1==s3 是比较哪个地址呢?
    5:hashMap中查找key时 int hash = hash(key.hashCode());
    不同的key经过hash()运算是否有可能的到相同的hash呢?
    e.hash == hash && ((k = e.key) == key || key.equals(k))这里一定要比较2个hash值相等吗?为什么
  2. A
    1,当然是对象在堆中的地址,因为引用可有很多,如果是引用的地址的话,那一个对象有多少个引用就有多少个hashcode,显然不对;
    2,对象地址是无法直接获取的,你拿了也没用,但是可以获得任何对象的hashcode,不是对象重载了hashCode()方法以后的,而是原生的:System.identityHashCode(Object x);
      通过System.identityHashCode出来的任何不同的对象的HashCode都是不同的,你通过Object.hashCode()返回的值发现不同的对象这个值相同是因为对象覆写了hashCode()方法。
    3,s1,s2,s3的hashcode相同是因为String类覆写了hashCode()方法,你看看源码就知道String的hahsCode只和String的内容(char[] value)有关,
    另外的解释是:他们相互equals返回true,所以hashCode()也应该相等();
    当然,System.identityHashCode(s1)与System.identityHashCode(s2)就不想等了。
    4,s1==s3比较的是System.identityHashCode(s1)和System.identityHashCode(s3)

ssh2开发 初始化hashmap对象到内存 供全局使用如何实现

  1. Q
    比如程序运行的时候,初始化时加载用户信息表里的数据,以键值对的形式放到hashmap中
    之后其他方法可以直接调用这个全局的hashmap的到用户的信息。。。。
    问题补充:这么说只需要定义成static就行了吗
  2. A
    static 表示全局
    final 表示只读
    这两者结合则实现了,单例共享。
    建议有时间的话,读一读这个:
    http://mougaidong-163-com.iteye.com/blog/994949

怪异问题!sql在pl/sql中执行结果与java jdbc执行结果不一致

  1. Q
    做一查询系统(struts2+myeclipse+tomcat+oracle9),一般先在pl/sql中测试sql语句,无问题后在action中使用oracle thin模式连接数据库,执行sql语句,然后将查询结果存入HashMap后输出至jsp页面。
    出现如下怪异问题:
    1、在pl/sql中测试sql语句时结果正常。结果中有6个字段,其中两个字段为count()函数统计出的数值。
    2、将在pl/sql中测试过的sql语句写入struts2的action中,通过jdbc thin模式执行,查询结果与pl/sql中测试结果不一致。
    count()函数统计的那两个字段的值不一致,暂未发现规律。数值接近,互有高低。
    在struts2的action中执行sql语句前,先打印sql语句,打印语句与pl/sql中测试语句一样,查询结果一致。
    在action中执行sql语句后在将rs(RecordSet)存入HashMap前,输出rs内容,count()统计出的数值结果已经不一致。
    该系统中类似查询功能有几个,实现方式方法相同,唯独这个出现pl/sql和jdbc执行同一句sql结果后部分字段数值不一致的诡异情况!
    烦请大家帮助分析、支招!不胜感激!!
    问题补充:lang_tu 写道向HashMap里存值时,键相同的值会被覆盖,比如:
    Map map = new HashMap();
    map.put("1", "1");
    map.put("1", "211");
    System.out.println("长度="+map.size()"   值="+map.get("1"));
    打印结果:长度=1   值=211
    因此你jsp页面显示的值可能会比sql语句查询的少


    问题是在向HashMap中存值之前就已经不一致了。
    问题补充:akunamotata 写道会不会是你pl/sql查询的table和jdbc查询的table根本不是一个table,但是是同名的,表空间不同。这个问题碰到过,纠结了很久,不知道能不能帮助你。


    多谢兄台帮忙分析,不会的,是同一条sql语句,pl/sql中测试后写到action中,完了jdbc执行前还打印sql语句,也是同一条,但结果就是不一致,单步追踪测试,在rs = stmt.executeQuery(sql);后,getString方法取值时已经不一致了。
    快疯了!


    问题补充:多谢大家帮忙分析!
    该功能只是查询,不涉及数据修改。
    本来只是查询得到的结果直接存rs,为测试又写了个临时表(即create table table_name as sql),结果发现存到临时表里的数据已经不一致了。同时jdbc有错误提示,代码如下,请大家帮忙再看看!
    type Exception report
    
    message 
    
    description The server encountered an internal error () that prevented it from fulfilling this request.
    
    exception 
    
    java.sql.SQLException: ORA-01003: ?????????
    
        oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
        oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
        oracle.jdbc.ttc7.v8Odscrarr.receive(v8Odscrarr.java:207)
        oracle.jdbc.ttc7.TTC7Protocol.describe(TTC7Protocol.java:770)
        oracle.jdbc.driver.OracleStatement.describe(OracleStatement.java:6572)
        oracle.jdbc.driver.OracleResultSetMetaData.<init>(OracleResultSetMetaData.java:59)
        oracle.jdbc.driver.OracleResultSetImpl.getMetaData(OracleResultSetImpl.java:163)
        yjcx.lfsbl.execute(lfsbl.java:97)
        sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        java.lang.reflect.Method.invoke(Method.java:597)
        com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)
        com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:280)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:243)
        com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:165)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:252)
        org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:122)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:179)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:235)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:89)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:130)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:126)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:138)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:165)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:179)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
        org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
        org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:488)
        org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
        org.extremecomponents.table.filter.AbstractExportFilter.doFilter(AbstractExportFilter.java:49)
    
    
    note The full stack trace of the root cause is available in the Apache Tomcat/6.0.13 logs.
    
    
    --------------------------------------------------------------------------------
    
    Apache Tomcat/6.0.13
     
    


    问题补充:多谢大家帮忙分、支招,问题找到了,我的sql语句的条件中有汉字,oracle字符集和java字符集不一致,结果导致了查询结果不一致。
    这里貌似只能有一个最佳答案,不能给所有参与的人散分,akunamotata比较积极,分就给你了,也谢谢参与的其他朋友!
  2. A
    pl/sql查询和jdbc查询,使用相同的排序方式...分析下结果不同之处,你也可以贴出来看看,帮你分析一下。