2017-07-31 49 views
0

的ArrayList我有以下的ArrayList List<DataSt> list1其中list1具有以下值(浮子):有效的方式來發現每個字段的最小/最大在對象

<25.89, 21.23> 
< 5.89, 1.23> 
< 3.69, 20.23> 
< 2.89, 121.23> 
<125.89, 231.23> 
. 
. 
. 
< 28.89, 41.23> 

而且DataSt具有以下結構:

public class DataSt { 
    private float a; 
    private float b; 

    public DataSt(float a , float b){ 
     this.a=a; 
     this.b=b; 
    } 
} 

現在我需要找到從第一列即最小,從<25.89, 5.89, 3.69, 2.89, 125.89 ... 28.89>它必須返回2.89

然後找到最大從<25.89, 5.89, 3.69, 2.89, 125.89 ... 28.89>它必須返回125.89

現在重複相同的第二列和存儲他們與4個不同的變量,分別說min_col1,max_col1,min_col2和max_col2分別。

min_col1 = 2.89 
max_col1 = 125.89 
min_col2 = 1.23 
max_col2 = 231.23 

我一直在尋找通過建議使用兩個for循環不同的解決方案是真正的時間耗費也有些線程使用流()這是找到整個列表(即不是每列)建議。

有沒有一種有效的方法來做到這一點?我也在看Apache Commons。

+0

你到目前爲止試過了什麼?你在哪裏遇到性能問題? – Flown

+2

如果你可以分享你已經擁有的代碼,那會很好。它表明你自己做出了努力,不僅僅是在尋找某人爲你寫代碼。還可以更容易地查看代碼中是否出現錯誤和/或是否可以改進 –

+0

請使用這些嵌套循環向我們展示您的努力。然後我們可以告訴你如何改進它。但是如果你的代碼完成了實際的工作,並且沒有性能問題,爲什麼改變一個工作解決方案? – Flown

回答

0

這是一個恥辱沒有FloatStream,但你可以擴大價值雙打,然後安全地縮小回來。

我假設你已經取消了A和B的獲得者,

if (list1.isEmpty()) 
{ 
    throw /*something*/; 
} 
min_col1 = (float) list1.stream().mapToDouble(DataSt::getA).min().getAsDouble(); 
max_col1 = (float) list1.stream().mapToDouble(DataSt::getA).max().getAsDouble(); 
min_col2 = (float) list1.stream().mapToDouble(DataSt::getB).min().getAsDouble(); 
max_col2 = (float) list1.stream().mapToDouble(DataSt::getB).max().getAsDouble(); 
+0

這比使用'.map()'而不是'.mapToDouble'在'min(),max()'中使用'Comparator.naturalOrder()'更有效嗎? –

+0

這是如何更有效?這樣你最終會循環4次。 –

+0

我完全忽略了效率方面。如果沒有測量過某個問題,或者定義了效率目標,那麼這是完全沒有意義的要求。在實踐中,這可能會比基於for-loop的解決方案性能低得多,並且明顯更清晰和可維護。 – Michael

1

如果您只需要查找這些值,則足以在列表中循環一次。我建議研究一下Big O符號,以瞭解算法的性能。

你可以做這樣的事情:

float min_col1 = Float.MAX_VALUE; 
float max_col1 = Float.MIN_VALUE; 
float min_col2 = Float.MAX_VALUE; 
float max_col2 = Float.MIN_VALUE; 

for (DataSt data : list1) { 

    if (data.getA() < min_col1) { 
     min_col1 = data.getA(); 
    } 

    if (data.getA() > max_col1) { 
     max_col1 = data.getA(); 
    } 

    if (data.getB() < min_col2) { 
     min_col2 = data.getB(); 
    } 

    if (data.getB() > max_col2) { 
     max_col2 = data.getB(); 
    } 
} 
+0

如果列表爲空,則您不得不檢查哨兵值的負載。 – Michael

+1

問題不在於處理邊緣情況,是嗎?這只是一次性完成的一般方法。 –

+0

那麼要麼在你的回答中提到或者改進代碼,否則就是一個不好的答案。 – Michael

0

我摸索出了一些樣品給你。

float Fmin = 0f; 
    float Fmax = 0f; 
    float Smin = 0f; 
    float Smax = 0f; 
    for (int i = 0; i < dataSts.size(); i++) 
    { 
     DataSt dataSt = dataSts.get(i); 
     float a = dataSt.getA(); 
     float b = dataSt.getB(); 
     if(i == 0) 
     { 
      Fmin = a; 
      Fmax = a; 
      Smin = b; 
      Smax = b; 
      continue; 
     } 

     if(a < Fmin) 
      Fmin = a; 

     if(b < Smin) 
      Smin = b; 

     if(a > Fmax) 
      Fmax = a; 

     if(b > Smax) 
      Smax = b; 

    } 
    System.out.println(Fmin +": "+Fmax+" : "+Smin+" : "+Smax); 
相關問題