【问题标题】:Convert SQL to java lambda将 SQL 转换为 java lambda
【发布时间】:2015-05-04 18:22:11
【问题描述】:

我有以下查询,我想将其转换为在我拥有的 List 类上使用。目标是将其转换为 java 8 lambda。我面临的主要问题是让“trademinuessincemidnight and paper”输出到新列表

AssetTotals 类当然会包含 4 个带有访问器的输出字段(price、countPapers、paper、trademinutessincemidnight)。

SELECT avg(price), count(price), paper, TRADEMINUTESSINCEMIDNIGHT FROM sgdata.ASSET group by TRADEMINUTESSINCEMIDNIGHT, paper order by paper, TRADEMINUTESSINCEMIDNIGHT

public class Asset implements Serializable, Comparable<Asset> {

    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id; // still set automatically

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    long sequenceNo;
    String Exchange;
    String Board;
    long time;
    String paper;
    long tradeTime;
    long quantity;
    double price;
    String source;
    String buyer;
    String seller;
    float changeSinceLast;
    String initator;
    long tradeTimeSinceMidnight;
    long tradeMinutesSinceMidnight;
    long daysSinceEpoch;


    public long getSequenceNo() {
        return sequenceNo;
    }
    public void setSequenceNo(long sequenceNo) {
        this.sequenceNo = sequenceNo;
    }
    public String getExchange() {
        return Exchange;
    }
    public void setExchange(String exchange) {
        Exchange = exchange;
    }
    public String getBoard() {
        return Board;
    }
    public void setBoard(String board) {
        Board = board;
    }
    public long getTime() {
        return time;
    }
    public void setTime(long time) {
        this.time = time;
    }
    public String getPaper() {
        return paper;
    }
    public void setPaper(String paper) {
        this.paper = paper;
    }
    public long getTradeTime() {
        return tradeTime;
    }
    public void setTradeTime(long tradeTime) {
        this.tradeTime = tradeTime;
    }
    public long getQuantity() {
        return quantity;
    }
    public void setQuantity(long quantity) {
        this.quantity = quantity;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getSource() {
        return source;
    }
    public void setSource(String source) {
        this.source = source;
    }
    public String getBuyer() {
        return buyer;
    }
    public void setBuyer(String buyer) {
        this.buyer = buyer;
    }
    public String getSeller() {
        return seller;
    }
    public void setSeller(String seller) {
        this.seller = seller;
    }
    public float getChangeSinceLast() {
        return changeSinceLast;
    }
    public void setChangeSinceLast(float changeSinceLast) {
        this.changeSinceLast = changeSinceLast;
    }
    public String getInitator() {
        return initator;
    }
    public void setInitator(String initator) {
        this.initator = initator;
    }

    public long getDaysSinceEpoch() {
        return daysSinceEpoch;
    }
    public void setDaysSinceEpoch(long daysSinceEpoch) {
        this.daysSinceEpoch = daysSinceEpoch;
    }
    public long getTradeTimeSinceMidnight() {
        return tradeTimeSinceMidnight;
    }
    public void setTradeTimeSinceMidnight(long tradeTimeSinceMidnight) {
        this.tradeTimeSinceMidnight = tradeTimeSinceMidnight;
    }

    public long getTradeMinutesSinceMidnight() {
        return tradeMinutesSinceMidnight;
    }
    public void setTradeMinutesSinceMidnight(long tradeMinutesSinceMidnight) {
        this.tradeMinutesSinceMidnight = tradeMinutesSinceMidnight;
    }


    @Override
    public boolean equals(Object obj) {

        return sequenceNo == ((Asset)obj).sequenceNo;

    }

    @Override
    public int compareTo(Asset otherAsset) {
        if (this.getSequenceNo() < otherAsset.getSequenceNo()) {
            return -1;
        }
        else if (this.getSequenceNo() == otherAsset.getSequenceNo()) {
            return 0;
        }
        return 1;
    }
    @Override
    public String toString() {
        return this.paper + " " + this.price + " " + this.tradeMinutesSinceMidnight;

    }

}

【问题讨论】:

  • 在大多数情况下,您最好让数据库为您执行查询,而不是尝试在 VM 中检索超出您需要的数据,然后执行 Java 代码来执行搜索和过滤。你想做什么,为什么?
  • 如果我有数据库中的信息,我会在数据库中完成。但是我正在实时使用列表并添加到该列表中。不将数据写入数据库并检索它的聚合。但我知道使用数据库会是什么样子,这就是我写它的原因。
  • 你能用你的 lambda 表达式展示你到目前为止所做的尝试吗?如果您可以展示到目前为止您的表达方式已经走了多远,然后就您无法使用的表达方式寻求具体帮助,而不是要求某人帮助您,您更有可能从其他人那里得到答案给你写表达式?

标签: java lambda java-8


【解决方案1】:
List<Asset> list=…;
Comparator<Asset> group=Comparator.comparing(Asset::getPaper)
                                  .thenComparing(Asset::getTradeMinutesSinceMidnight);
list.stream().collect(Collectors.groupingBy(
        Function.identity(), ()->new TreeMap<>(group),
        Collectors.summarizingDouble(Asset::getPrice)))
    .forEach((a,p)-> System.out.println(
             a.getPaper()
       +"\t"+a.getTradeMinutesSinceMidnight()
       +"\t"+p.getAverage()
       +"\t"+p.getCount()));

由于您想按相同的属性进行分组和排序,实现此目的的最简单方法是收集到使用适当Comparator 的排序映射中。生成的映射将具有 Asset 实例作为键,这些实例对这些属性具有不同的元组,但您不得对其他属性做出任何假设,因为键对象只是从组中挑选的一个任意实例.

映射的值由下游收集器确定,它是一个summarizingDouble(Asset::getPrice) 收集器,它将生成一个DoubleSummaryStatistics 的实例,其中包含price 属性、maxmin 的所有聚合值, averagecountsum。我根据您的问题在此处打印了count,但是,我怀疑您实际上想要sum,但它很容易更改。

也与this answer 比较,后者还讨论了按一个属性分组和聚合多个属性的相关任务。

【讨论】:

  • 哇,这是一种非常复杂的方法,在 SQL 中需要一行。我会尽快测试的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
  • 2017-09-25
  • 1970-01-01
相关资源
最近更新 更多