Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    35

    [JAVA] Ordinamento anomalo

    Ciao a tutti,
    mi è capitata una situazione anomala dalla quale non riesco ad uscirne
    Sto lavorando su un'applicazione realizzata qualche anno fa in Java.
    Il problema è il seguente:

    si esegue una query con tanto di "ORDER BY" ed i risultati vengono inseriti in un Vector.
    Successivamente si manipolano gli oggetti di questo vector.

    Il problema è che quando eseguo la query facendo girare il software in locale, i risultati della query sono "ordinati" correttamente.
    Quando invece la eseguo facendo girare il software in un altro ambiente, i risultati non sono ordinati correttamente.
    In particolare, per farvi un esempio, invece di ordinare i dati nel seguente modo:

    VA1
    V1

    li ordina così:

    V1
    VA1

    Come posso uscirne secondo voi da questa situazione?
    Grazie.
    Saluti

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Non ho capito dove sia effettivamente il problema... di che tipo di ordinamento stiamo parlando? Lessicografico? Perchè se così fosse, l'ordinamento corretto è il secondo e non il primo...

    Prova a spiegare meglio la situazione, con un esempio più completo e, possibilmente, postando la parte di codice che effettua la query.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    35
    La query è la seguente:

    SELECT C_TIPO_QDRO, C_QDRO, C_QDRO_LVL_SUP, F_RPTT, F_RPTT_ATVT_NP, T_REC_MNSTL
    FROM QDRO_T008
    WHERE C_MODEL ="XXX" AND V_ANNO_RIF_MODEL="2009"
    ORDER BY T_REC_MNSTL ASC, C_QDRO ASC

    L'ordinamento è di tipo lessicografico.
    Il problema è che quando viene eseguita dal software installato sull'application server che ho in locale, funziona come ci si aspetta (nell'esempio di prima viene messo prima VA1 e poi V1).
    Quando invece viene eseguita dal software installato su un application server di un'altra macchina funziona in maniera anomala (viene messo prima V1 e poi VA1).

    Ho pensato al charset ma booooohhhhhhhhhhhhh.

    HELP ME PLEASE

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Originariamente inviato da Carchi
    L'ordinamento è di tipo lessicografico.
    Il problema è che quando viene eseguita dal software installato sull'application server che ho in locale, funziona come ci si aspetta (nell'esempio di prima viene messo prima VA1 e poi V1).
    E io ti ripeto che mi aspetterei il contrario: il carattere '1', nell'ordinamento lessicografico, viene prima del carattere 'A', in quanto ha un peso inferiore: '1' = 49; 'A' = 65.
    Quindi, a mio avviso, è il software installato sull'application server della tua macchina che andrebbe ricontrollato...

    Quando invece viene eseguita dal software installato su un application server di un'altra macchina funziona in maniera anomala (viene messo prima V1 e poi VA1).

    Ho pensato al charset ma booooohhhhhhhhhhhhh.

    HELP ME PLEASE
    Vedi punto precedente.

    Ad ogni modo, va bene che tu abbia postato la query, ma se non sappiamo nulla di questa applicazione Java, non sappiamo nulla di cosa sia sto "software installato sull'application server", non sappiamo nulla dell'application server, non sappiamo nulla del DB... che ti possiamo dire se non "guarda che è quello sulla tua macchina che sta sbagliando"?


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    35
    Hai ragione eheh.

    Dunque...l'application server è Oracle Weblogic Server 10.3 (ex Bea in pratica), il DB è Oracle 10 g e la versione della JRE utilizzata è la 1.5

    In effetti il carattere '1' viene prima del carattere 'A', ma io vorrei che accadesse il contrario, ovvero che l'ordinamento dia precedenza alle lettere rispetto ai numeri.

    Ti spiego il funzionamento della parte di software che crea problemi:

    viene fatta la query che ho postato in precedenza e vengono creati tanti oggetti quanti sono i records che restituisce la query.
    Tutti questi oggetti vengono inseriti in un Vector sul quale vengono fatte altre operazioni.
    Ora...l'ordine in cui gli oggetti vengono inseriti nel Vector è di tipo lessicografico in base al valore degli elementi della colonna "C_QDRO" del DB, quindi al valore dell'attributo cQdro degli oggetti da inserire.
    Quindi, giustamente come tu dici, vengono inseriti prima i valori letterali e poi quelli numerici.
    Quindi, ad esempio, i valori ordinati sono:

    V1
    V2
    VA
    VB
    VC

    Io invece devo assolutamente fare in modo che i valori ordinati siano:

    VA
    VB
    VC
    V1
    V2

    L'anomalia sta nel fatto che quando il software gira in locale funziona come vorrei (mette prima le lettere, poi i numeri); quando invece gira in un altro ambiente non funziona come vorrei (mette prima i numeri poi le lettere).
    Il due ambienti "utilizzano" la stessa istanza del DB ma (ovviamente) istanze diverse dell'application server.
    In locale c'è Windows XP, nell'altro ambiente c'è Linux SUSE.

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Non conosco quell'application server, quindi non ti so dire se c'è qualche tipo di impostazione che possa influire sull'ordinamento all'interno di una query... ma ne dubito.

    Ciò che è più probabile (e che quindi dovresti controllare) è che vi sia da qualche parte nella tua applicazione una qualche policy di ordinamento.... perchè per ottenere l'ordinamento che desideri (prima le lettere e poi i numeri) ci deve essere qualcosa di più: l'ordinamento lessicografico standard, infatti, non si comporta in quel modo.

    Quello che puoi fare (e che dovresti fare, per avere la garanzia di quel tipo di ordinamento, che ripeto è particolareggiato) è quello di creare tu l'algoritmo di ordinamento e applicarlo dopo che la query è stata eseguita. In questo modo, a prescindere dall'ordine con cui questi dati vengono estratti dal DB, la garanzia dell'ordinamento particolare la fornisci tu.

    Questo può essere fatto in modo "abbastanza semplice", utilizzando i metodi sort() delle Collection e implementando l'interfaccia Comparable negli oggetti che rappresentano i record, in modo da fornire loro il metodo di comparazione tra due oggetti. Ho messo tra virgolette quel "abbastanza semplice" proprio perchè dovrai essere tu a fare in modo che ciascuna lettera venga vista come "più leggera" di ciascuna cifra. Con un po' di lavoro ci si riesce.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Ti posto un esempio: la seguente classe (che probabilmente può essere ottimizzata) rappresenta una stringa che verrà sempre ordinata (rispetto ad altri oggetti dello stesso tipo) secondo l'algoritmo che interessa a te, ovvero con le lettere prima delle cifre:

    codice:
    public class MiaStringa implements Comparable {
       private String str;
       public MiaStringa(String str) { this.str = str; }
       public String toString() { return str; }
       public int compareTo(Object obj) {
          int retVal = 0;
          MiaStringa ms = (MiaStringa) obj;
          char[] str1 = str.toCharArray();
          char[] str2 = ms.toString().toCharArray();
    
          // Controllo subito i casi base
          if (str1.length == 0) {
             // In questo caso this è la stringa vuota.
             // Questo oggetto può essere solo minore o
             // al massimo uguale a quello passato
             retVal = (str2.length > 0) ? -1 : 0;
    
          } else {
    
             if (str2.length == 0) {
                // L'oggetto passato è la stringa vuota.
                // Questo oggetto è ovviamente maggiore
                retVal = 1;
    
             } else {
    
                for(int i=0; i<str1.length; i++) {
                   if (i < str2.length) {
                      if ( Character.isDigit(str1[i]) ) {
                         if ( Character.isDigit(str2[i]) ) {
                            retVal = (str1[i] - str2[i]);
                            if (retVal != 0) break;
                         } else {
                            retVal = 1;
                            break;
                         }
                      } else {
                         if ( Character.isDigit(str2[i]) ) {
                            retVal = -1;
                            break;
                         } else {
                            retVal = (str1[i] - str2[i]);
                            if (retVal != 0) break;
                         }
                      }
                   } else {
                      // L'oggetto passato è un "left()" di questo.
                      retVal = 1;
                      break;
                   }
                }
    
             }
          }
    
          return retVal;
       }
    }
    Questo semplice esempio dimostra quanto appena detto:

    codice:
    import java.util.*;
    public class Ordina {
       public static void main(String[] args) {
          MiaStringa[] ms = generaRandom( 10 );
          Arrays.sort( ms );
          for(int i=0; i<10; i++) {
             System.out.println( ms[i] );
          }
       }
    
       private static MiaStringa[] generaRandom(int quanti) {
          MiaStringa[] ret = new MiaStringa[quanti];
          for(int i=0; i<quanti; i++) {
             String valore = generStr();
             ret[i] = new MiaStringa( valore );
          }
          return ret;
       }
    
       private static String generStr() {
          String ret = "";
          int rand = (int) (Integer.MAX_VALUE * Math.random());
          ret = Integer.toHexString( rand );
          return ret;
       }
    }
    L'esempio d'uso genera un array di 10 oggetti MiaStringa. Ciascun oggetto viene generato casualmente (viene preso un intero a caso fra 0 e MAX_VALUE e convertito in esadecimale), quindi l'intero array viene ordinato tramite il metodo sort() della classe Arrays (che usa, per l'appunto, oggetti Comparable).
    La specifica dell'ordinamento è di imporre che ciascun carattere alfabetico venga prima di qualunque cifra. Il confronto fra cifre e il confronto fra caratteri alfabetici, segue l'ordinamento classico.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  8. #8
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    35
    Ho RISOLTOOOOOOOOOOOOOOOOOO!!!!!!!!!!!!!!!!


    GRAZIE INFINITE LELE!!!!

    Siccome il mio non era un Array ma un Vector, ho usato il metodo sort() di Collections!

    In pratica ho fatto così (dopo essermi letto un pò di documentazione ovviamente):

    Ho creato un oggetto Comparator:
    codice:
              Comparator cmp = new Comparator(){
                  public int compare(Object a1, Object a2) {
                      MiaClass anag1 = (MiaClass)a1;
                      MiaClass anag2 = (MiaClass )a2;
                      return anag1.compareTo(anag2);
                  }
    
                    };
    poi ho ordinato il Vector usando il metodo sort() di Collections:

    codice:
    Collections.sort(MioVector, cmp);
    ed il metodo compareTo(Object o) l'ho implementato + o - come quello che hai postato prima.

    Grazie ancora Lele, sei stato gentilissimo ed una salvezza
    Ciao!!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.