Turn an SQL command into Lambda or Java 8 Stream

Asked

Viewed 133 times

-1

I’m starting in Java 8 and would like to turn the SQL command below into a lambda function:

SELECT * FROM Correspondencia c, (SELECT entidadeOrigem, MAX(m1) 
similaridadeMaxima FROM Correspondencia WHERE m1 <> 0 GROUP BY 
entidadeOrigem) r WHERE c.entidadeOrigem = r.entidadeOrigem AND c.m1 = 
r.similaridadeMaxima

I created the Class Correspondência with getters and setters.

public class Correspondencia {
    
    int codigo;
    String nome;
    String entidadeOrigem;
    String EntidadeDestino;
    double m1;
    double m2;
    double m3;
    double medMax;
    double dem;
    
    
    public int getCodigo() {
        return codigo;
    }
    public void setCodigo(int codigo) {
        this.codigo = codigo;
    }
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public String getEntidadeOrigem() {
        return entidadeOrigem;
    }
    public void setEntidadeOrigem(String entidadeOrigem) {
        this.entidadeOrigem = entidadeOrigem;
    }
    public String getEntidadeDestino() {
        return EntidadeDestino;
    }
    public void setEntidadeDestino(String entidadeDestino) {
        EntidadeDestino = entidadeDestino;
    }
    public double getM1() {
        return m1;
    }
    public void setM1(double m1) {
        this.m1 = m1;
    }
    public double getM2() {
        return m2;
    }
    public void setM2(double m2) {
        this.m2 = m2;
    }
    public double getM3() {
        return m3;
    }
    public void setM3(double m3) {
        this.m3 = m3;
    }
    public double getMedMax() {
        return medMax;
    }
    public void setMedMax(double medMax) {
        this.medMax = medMax;
    }
    public double getDem() {
        return dem;
    }
    public void setDem(double dem) {
        this.dem = dem;
    }
}

I want to turn the SQL query into a Java 8 stream or mbda expression.

I created a list of Correspondencia:

List<Correspondencia> cor = new ArrayList<>(); 
cor.add(new Correspondencia(41,"Paper_Organization","Paper", "Organization",0,0,0.14,0.04,0.23,0.08")); 
cor.add(new Correspondencia(11,"email_hasanemail","email", "hasanemail",0,0.19,0.21,0.19,0,0.12)); 
cor.add(new Correspondencia(31,"Review_Reviewer","Review","Reviewer",0,0.36,0.5,0.41,0,0.25)); 
cor.add(new Correspondencia(01,"PaperAbstract_Abstract","PaperAbstract","Abstract", 0,0.33,0.45,0.32,0,0.22));

Now I want to filter the course with Lambda or Stream according to the query:

SELECT * FROM Correspondencia c, (SELECT entidadeOrigem, MAX(m1) similaridadeMaxima FROM Correspondencia WHERE m1 <> 0 GROUP BY entidadeOrigem) r WHERE c.entidadeOrigem = r.entidadeOrigem AND c.m1 = r.similaridadeMaxima

However, it would be clear the return of the sql query to

List<Correspondencia> cor = new ArrayList<Correspondencia>();

cor.add(new Correspondencia(41,"Paper_Organization","Paper", "Organization",0,0.14,0.04,0.23,0.08));
cor.add(new Correspondencia(22,"Paper_Organization","Paper", "Organization",0,0.15,0.04,0.23,0.08));
cor.add(new Correspondencia(22,"Paper_Organization","Paper", "Organization",0,0.36,0.04,0.23,0.08));
cor.add(new Correspondencia(11,"email_hasanemail","email", "hasanemail",0.19,0.21,0.19,0.,0.12));
cor.add(new Correspondencia(11,"email_hasanemail","email", "hasanemail",0.25,0.21,0.19,0.,0.12));
cor.add(new Correspondencia(11,"email_hasanemail","email", "hasanemail",0.37,0.21,0.19,0.,0.12));
cor.add(new Correspondencia(31,"Review_Reviewer","Review","Reviewer",0.36,0.5,0.41,0.,0.25));
cor.add(new Correspondencia(31,"Review_Reviewer","Review","Reviewer",0.38,0.5,0.41,0.,0.25));
cor.add(new Correspondencia(31,"Review_Reviewer","Review","Reviewer",0.37,0.5,0.41,0.,0.25));
cor.add(new Correspondencia(32,"email_hasanemail","email", "hasanemail",0.36,0.5,0.41,0.,0.25));
cor.add(new Correspondencia(01,"PaperAbstract_Abstract","PaperAbstract","Abstract", 0.33,0.45,0.32,0.,0.22));
cor.add(new Correspondencia(01,"PaperAbstract_Abstract","PaperAbstract","Abstract", 0.37,0.45,0.32,0.,0.22));

that would return me as a result the higher value of M1 grouped by the entity:

22,"Paper_Organization","Paper", "Organization",0,0.36,0.04,0.23,0.08
11,"email_hasanemail","email", "hasanemail",0.37,0.21,0.19,0.,0.12
31,"Review_Reviewer","Review","Reviewer",0.38,0.5,0.41,0.,0.25
01,"PaperAbstract_Abstract","PaperAbstract","Abstract", 0.37,0.45,0.32,0.,0.22

1 answer

-1

Editing: You need to use the Java Stream library. By the result of your query you return Matching with higher M1.

The command filter(x -> x.getM1() != 0) is the equivalent of where SQL. To use the filter you create an object by following the lambda definition (in this case the object x) and use an expression that must return trueor false.

The command .max(Comparator.comparing(x -> x.getM1())) is very similar to the max SQL, only it expects an object of the type Comparator. The Comparator API provides a method to write comparison using lambda, only instead of a Boolean, the Comparator expects a value to be able to compare - in this case, we pass the value of M1.

Below is an example code for how to implement this using Stream.

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.Comparator;

public class JavaFiddle
{
    public static void main(String[] args)
    {
        List<Correspondencia> cor = new ArrayList<Correspondencia>();

        cor.add(new Correspondencia(41,"Paper_Organization","Paper", "Organization",0,0.14,0.04,0.23,0.08));
        cor.add(new Correspondencia(11,"email_hasanemail","email", "hasanemail",0.19,0.21,0.19,0.,0.12));
        cor.add(new Correspondencia(31,"Review_Reviewer","Review","Reviewer",0.36,0.5,0.41,0.,0.25));
        cor.add(new Correspondencia(01,"PaperAbstract_Abstract","PaperAbstract","Abstract", 0.33,0.45,0.32,0.,0.22));

        Correspondencia maxM1 = cor.stream()
            .filter(x -> x.getM1() != 0)
            .max(Comparator.comparing(x -> x.getM1()))
            .get();

        System.out.println(maxM1);
    }
}



class Correspondencia {
    int codigo;
    String nome;
    String entidadeOrigem;
    String EntidadeDestino;
    double m1;
    double m2;
    double m3;
    double medMax;
    double dem;

    public Correspondencia(int codigo, String nome, String entidadeOrigem,
        String entidadeDestino, double m1, double m2, double m3, double medMax,
        double dem) {
        this.codigo = codigo;
        this.nome = nome;
        this.entidadeOrigem = entidadeOrigem;
        this.EntidadeDestino = entidadeDestino;
        this.m1 = m1;
        this.m2 = m2;
        this.m3 = m3;
        this.medMax = medMax;
        this.dem = dem;
    }


    public int getCodigo() {
        return codigo;
    }
    public void setCodigo(int codigo) {
        this.codigo = codigo;
    }
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public String getEntidadeOrigem() {
        return entidadeOrigem;
    }
    public void setEntidadeOrigem(String entidadeOrigem) {
        this.entidadeOrigem = entidadeOrigem;
    }
    public String getEntidadeDestino() {
        return EntidadeDestino;
    }
    public void setEntidadeDestino(String entidadeDestino) {
        EntidadeDestino = entidadeDestino;
    }
    public double getM1() {
        return m1;
    }
    public void setM1(double m1) {
        this.m1 = m1;
    }
    public double getM2() {
        return m2;
    }
    public void setM2(double m2) {
        this.m2 = m2;
    }
    public double getM3() {
        return m3;
    }
    public void setM3(double m3) {
        this.m3 = m3;
    }
    public double getMedMax() {
        return medMax;
    }
    public void setMedMax(double medMax) {
        this.medMax = medMax;
    }
    public double getDem() {
        return dem;
    }
    public void setDem(double dem) {
        this.dem = dem;
    }
}

Original answer: The class itself doesn’t explain much about its context... Where it actually needs to be modified is where you use the query... assuming you use Hibernate, the code would look something like this (assuming that sess is your hibernate session):

List correspondencias = sess.createCriteria(Correspondencia.class)
    .add( Restrictions.ne("m1", new Integer(0)) )
    .list();

You can get more information in the Hibernate documentation: http://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/html/querycriteria.html

For a list of commands you can use in Restrictions (which would be equivalent to WHERE in SQL) see the following link: https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/criterion/Restrictions.html

  • The problem is that it is only returning the higher value of M1. And what I need is that return of the highest value of each repeated item of M1 by the entityOrigem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.