Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    Unire dua ArrayList di oggetti senza duplicati

    ciao!

    creo due ArrayList di questo tipo eseguendo query su db diversi:
    codice:
    @Setter
    @Getter
    @AllArgsConstructor
    public class Timesheet {
      Integer idTimeSheet;
      Timestamp dataOraInizio;
      Timestamp dataOraFine;
      Integer minLvaorate;
    }
    devo unire queste due liste, ma levando i duplicati.
    i duplicati li devo trovare in base al campo idTimeSheet.

    come posso fare?

    questo il codice in cui riempio le liste:
    codice:
        MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
        mapSqlParameterSource.addValue("id", idProgetto);
    
    
        String queryOld = "SELECT * FROM Timesheet " +
            "INNER JOIN Progetto ON idProgetto = Timesheet.codProgetto " +
            "WHERE Timesheet.codProgetto = :id";
        List<Timesheet> listOld = jdbcTemplate.query(
            queryOld,
            mapSqlParameterSource,
            (rs, rowNum) -> new Timesheet(
                rs.getInt("idTimeSheet"),
                rs.getTimestamp("DataOraInizio"),
                rs.getTimestamp("DataOraFine"),
                rs.getInt("MinLavorate")
            )
        );
    
    
        String queryNew = "SELECT * FROM timesheets " +
            "INNER JOIN ps_progetto_sede ON id_sede = cod_sede_progetto " +
            "WHERE id_progetto = :id";
        List<Timesheet> listNew = mysqlTemplate.query(
            queryNew,
            mapSqlParameterSource,
            (rs, rowNum) -> new Timesheet(
                rs.getInt("id_timesheet_old"),
                null,
                null,
                0
            )
        );
    
    // UNIRE LISTE SENZA DUPLICATI
    ho provato a cercare in giro, ma ho trovato parecchi esempi in cui restituiscono nuovi ArrayList di stringhe/int.
    oppure partono dal presupposto di avere ArrayList con oggetti "semplici" e non custom come nel mio caso.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,261
    Quote Originariamente inviata da fermat Visualizza il messaggio
    devo unire queste due liste, ma levando i duplicati.
    i duplicati li devo trovare in base al campo idTimeSheet.

    come posso fare?
    Ci sono almeno 2 scenari:

    a) Se puoi fare in modo che la tua classe Timesheet tratti la "uguaglianza" degli oggetti (ovvero equals() e hashCode()) basata SOLO su idTimeSheet, allora ti basta buttare tutti gli oggetti in un HashSet<Timesheet> e hai tolto tutti i duplicati.

    b) Se non puoi/vuoi avere la uguaglianza di oggetti Timesheet basata su idTimeSheet, ti basta tenere un HashSet<Integer>. Se non trovi nel set un idTimeSheet, è "nuovo" (lo tieni - e aggiungi nel set); se lo trovi. è "duplicato" (lo scarti).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    ciao!

    ho fatto delle modifiche ieri, e penso di star facendo correttamente.
    penso che il problema siano proprio i dati che mi arrivano.
    dato che mi arrivano "sporchi" mi sembra che non elimini i duplicati, ma in verità il codice è corretto.

    domani controllo bene.
    intanto grazie!!

  4. #4
    ciao!

    allora, ho fatto un pò di modifiche:
    codice:
    import lombok.AllArgsConstructor;
    import lombok.EqualsAndHashCode;
    import lombok.Getter;
    import lombok.Setter;
    
    
    import java.sql.Timestamp;
    
    
    @Setter
    @Getter
    @AllArgsConstructor
    @EqualsAndHashCode(exclude = {"dataOraInizio", "dataOraFine", "minLvaorate"})
    public class Timesheet {
      Integer idTimeSheet;
      Timestamp dataOraInizio;
      Timestamp dataOraFine;
      Integer minLvaorate;
    }
    poi:
    codice:
    @Override
      public CheckTimesheet checkTimesheets(int idProgetto, String sendEmail) {
        MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
        mapSqlParameterSource.addValue("id", idProgetto);
    
    
        String queryOld = "SELECT * FROM Timesheet WHERE (codProgetto > 888 AND codProgetto < 932)";
        List<Timesheet> listOld = jdbcTemplate.query(
            queryOld,
            mapSqlParameterSource,
            (rs, rowNum) -> new Timesheet(
                rs.getInt("idTimeSheet"),
                rs.getTimestamp("DataOraInizio"),
                rs.getTimestamp("DataOraFine"),
                rs.getInt("MinLavorate")
            )
        );
    
    
        String queryNew = "SELECT * FROM timesheets " +
            "WHERE (cod_sede_progetto > 888 AND cod_sede_progetto < 932) " +
            "AND cancellato = 0";
        List<Timesheet> listNew = mysqlTemplate.query(
            queryNew,
            mapSqlParameterSource,
            (rs, rowNum) -> new Timesheet(
                rs.getInt("id_timesheet_old"),
                null,
                null,
                0
            )
        );
    
    
        List<Timesheet> listMerged = new ArrayList<>();
        listMerged.addAll(listOld);
        listMerged.addAll(listNew);
    
    
        Set<Timesheet> s = new HashSet<>(listMerged);
        List<Timesheet> list = new ArrayList<>(s);
    
    
        System.out.println("VECCHIO: " + listOld.size());
        System.out.println("NUOVO: " + listNew.size());
        System.out.println("TOTALE: " + listMerged.size());
        System.out.println("FINALE: " + list.size());
    
    
        return new CheckTimesheet(listOld.size(), listNew.size(), list);
      }
    ma mi ritorna dei dati assurdi:
    codice:
    VECCHIO: 7295
    NUOVO: 6472
    TOTALE: 13767
    FINALE: 7299
    quello che non riesco a capire, e che ovviamente non dipende da voi, è se è sbagliata la logica/codice, oppure è un problema di dati.
    ma penso sia più un problema di dati, visto che se li simulo mettendoli a mano funziona tutto correttamente.

  5. #5
    ok forse ho capito, sto sbagliando io.

    ho rifatto le query prendendo un solo record e questo è quello che mi compare:
    codice:
    VECCHIO: 1
    NUOVO: 1
    TOTALE: 2
    FINALE: 1
    ma ho sbagliato io ad impostare la cosa.
    a me non serve che ne sia uno, ma che se è doppio venga proprio eliminato.
    in sostanza il risultato dovrebbe essere così:

    codice:
    VECCHIO: 1
    NUOVO: 1
    TOTALE: 2
    FINALE: 0
    cioè nella nuova lista dovrei mettere solo quelli che sono sul vecchio e non sul nuovo.

    ---------------

    EDIT

    dovrei aver risolto così:
    codice:
    List<Timesheet> list = new ArrayList<>(listOld);
    list.removeAll(listNew);
    Ultima modifica di fermat; 09-01-2025 a 10:38

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 © 2025 vBulletin Solutions, Inc. All rights reserved.