0

我有交易列表,每个交易现在都有一些属性,例如来源,从交易列表中,我想获得所有具有相同来源价值的交易并将它们组合成一个交易,例如

tradeName      quote           source            quantity      price 
Google          GOOG           Goldman Sachs        15           610  
Microsoft       MSFT           Barclays             400          28
Google          GOOG           Goldman Sachs        45           610  
Google          GOOG           Goldman Sachs        40           610  
Microsoft       MSFT           Barclays             1000          28

现在基于源信息,我应该合并交易,所以我更新的交易清单将是

tradeName      quote           source            quantity        price 
Google          GOOG           Goldman Sachs        100           610  
Microsoft       MSFT           Barclays             1400           28

我不确定比较部分,如何解决?


尝试了以下方法,

for (Trade trade : tradeList)
{
   //Not sure how to compare this.trade.source with all sources 
   //of all trades present in the trade.
   //Logic should be if source matches then quantity should be added 
   //but am not sure how comparison would work.  
}

Class Trade
{

private tradeName;
private quote;
private source;
private quantity;
private price;

//Getters and Setters for each of above mentioned attributes. 

}
4

4 回答 4

2

我想我会创建一个HashMap<String, Trade>,tradeName+quote+source用作键,然后将列表中的每笔交易添加到地图中的相应项目中。

例子:

Map<String, Trade> map = new HashMap<String, Trade>();
for (Trade trade : tradeList) {
    String key = trade.tradeName + "#" + trade.quote + "#" + trade.source; // signature, what you merge by 
    if (map.containsKey(key)) {
        map.put(key, trade); // the first trade with such a signature 
    } else {
        // not the first, so merge it with the existing one
        map.get(key).add(trade); // you'll have to implement the Trade.add() method
    }
}
List<Trade> merged = new LinkedList<Trade>(map.values());
于 2012-08-02T16:01:30.337 回答
1

虽然我同意使用 Hashmap 可能更有效,但我更喜欢尝试保留 OP 提供的方法。如果我们要遍历每个成员,让我们检查一下到目前为止我们是否找到了那个成员。如果是这样,修改他。如果没有,加他。我建议将所有这些都写入一个新列表,然后对新列表做任何你想做的事情(将旧列表设置为新列表,打印新列表,将新列表通过电子邮件发送给俄罗斯总统,等等)。

那么像下面这样的事情呢?(我没有编译这个,所以请原谅任何错别字)

//Create a new list to store our "simplified" results into
ArrayList<Trade> newTradeList = new ArrayList<Trade>(tradeList.size());

//For each trade in the old list, call it "trade" and...
for(Trade trade : tradeList){

    //First we ask, is there already a trade in this list with the same source?
    //indexOf finds where in the array the element lives. I store that result in index
    int index = newTradeList.indexOf(trade);

    //If the element isn't in our list yet, indexOf will return -1.
    //If the result is NOT -1, then we have already seen a trade with this source before
    if(index != -1) {
         //In that case, get that element. We know what index it lives at so grab it.
         Trade t = newTradeList.get(index);
         //Then, do whatever operations to combine the two trades. I assumed you add the quantities. 
         //So the trade in our new list's quantity should be what it was, plus the new trade's quantity
         t.setQuantity(t.getQuantity() + trade.getQuantity());
    } 

    //But if we have never seen this source before, let's add it to our our new list
    else {
         newTradeList.add(trade);
    }
}

当然,这是做一些假设。为了.indexOf工作,您需要您的Tradeequals正确定义方法(检查来源,或来源和价格是否相同 - 任何看起来正确的东西)。如果你重新定义equals,你真的应该也定义hashCode。它还假设您有一个方法.addQuantity,因为它使代码比获取和集合的组合更简洁。


HashMap 的优点是几乎即时 (O(1)) 检查元素是否已经存在,并确保其中的元素是唯一的(因为 hashmap 是一个 Set,并且一个集合不能有重复的元素)。代码看起来很相似,除了我们可以利用 HashMap 的containsKey方法,而不是indexOf.

于 2012-08-02T16:23:37.417 回答
0

请检查这两种方法:

Java 豆:

public class Trade {

private String tradeName;
private String quote;
private String source;
private Integer quantity;
private Integer price;

public String getTradeName() {
    return tradeName;
}

public void setTradeName(String tradeName) {
    this.tradeName = tradeName;
}

public String getQuote() {
    return quote;
}

public void setQuote(String quote) {
    this.quote = quote;
}

public String getSource() {
    return source;
}

public void setSource(String source) {
    this.source = source;
}

public Integer getQuantity() {
    return quantity;
}

public void setQuantity(Integer quantity) {
    this.quantity = quantity;
}

public Integer getPrice() {
    return price;
}

public void setPrice(Integer price) {
    this.price = price;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((source == null) ? 0 : source.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Trade other = (Trade) obj;
    if (source == null) {
        if (other.source != null)
            return false;
    } else if (!source.equals(other.source))
        return false;
    return true;
}

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("Trade [tradeName=");
    builder.append(tradeName);
    builder.append(", quote=");
    builder.append(quote);
    builder.append(", source=");
    builder.append(source);
    builder.append(", quantity=");
    builder.append(quantity);
    builder.append(", price=");
    builder.append(price);
    builder.append("]");
    return builder.toString();
}
}

- 编辑 -

检查一下,这很简单:

import java.util.ArrayList;
import java.util.List;

public class TradeTest {

/**
 * @param args
 */
public static void main(String[] args) {
    Trade t1 = new Trade();
    t1.setPrice(610);
    t1.setQuantity(15);
    t1.setQuote("GOOG");
    t1.setSource("Goldman Sachs");
    t1.setTradeName("Google");

    Trade t2 = new Trade();
    t2.setPrice(28);
    t2.setQuantity(400);
    t2.setQuote("MSFT");
    t2.setSource("Barclays");
    t2.setTradeName("Microsoft");

    Trade t3 = new Trade();
    t3.setPrice(610);
    t3.setQuantity(45);
    t3.setQuote("GOOG");
    t3.setSource("Goldman Sachs");
    t3.setTradeName("Google");

    Trade t4 = new Trade();
    t4.setPrice(610);
    t4.setQuantity(40);
    t4.setQuote("GOOG");
    t4.setSource("Goldman Sachs");
    t4.setTradeName("Google");

    Trade t5 = new Trade();
    t5.setPrice(28);
    t5.setQuantity(1000);
    t5.setQuote("MSFT");
    t5.setSource("Barclays");
    t5.setTradeName("Microsoft");

    List<Trade> trades = new ArrayList<Trade>();
    trades.add(t1);
    trades.add(t2);
    trades.add(t3);
    trades.add(t4);
    trades.add(t5);

    List<Trade> googleTrades = new ArrayList<Trade>();
    List<Trade> microsoftTrades = new ArrayList<Trade>();

    Integer googleQuantities = 0;
    Integer microsoftQuantities = 0;

    for (Trade trade : trades) {
        if (trade.getSource().equals("Goldman Sachs")) {
            googleTrades.clear();
            googleQuantities += trade.getQuantity();
            trade.setQuantity(googleQuantities);
            googleTrades.add(trade);
        } else if (trade.getSource().equals("Barclays")) {
            microsoftTrades.clear();
            microsoftQuantities += trade.getQuantity();
            trade.setQuantity(microsoftQuantities);
            microsoftTrades.add(trade);
        }
    }

    System.out.println("Google trades: \n");
    System.out.println(googleTrades);
    System.out.println("\n");
    System.out.println("Microsoft trades: \n");
    System.out.println(microsoftTrades);

}

}

检查这是否适合您。

于 2012-08-02T17:13:39.583 回答
-1

我觉得应该这样做。

Trade gsTrades = new Trade();
    Trade barclaysTrades = new Trade();

    for(Trade trade: tradeList){
        if(trade.getSource().equals("GS")){
            gsTrades.setQuantity(gsTrades.getQuantity()+trade.getQuantity());
            gsTrades.setPrice(gsTrades.getPrice()+trade.getPrice());
        }else{
            barclaysTrades.setQuantity(barclaysTrades.getQuantity()+trade.getQuantity());
            barclaysTrades.setPrice(barclaysTrades.getPrice()+trade.getQuantity());
        }
    }
    System.out.println("GS trade details = " + gsTrades.toString());
    System.out.println("Barclays trade details = " + barclaysTrades.toString());
于 2012-08-02T16:38:03.057 回答