2017-04-25 40 views
2

我正在嘗試重寫並重新計算下面的代碼,但在末尾沒有相同的結果(列表中的vgs不包含相同的結果執行這兩個功能)。 此外,我不明白我的代碼下面有什麼問題。有人能告訴我如何才能保持我的元素在List和Var中的順序,而不是Var和OrVars? 這個函數的目標是刪除和變量的所有空或空的String元素值& notVars list +我的字符串元素值和變量中的所有重複元素& notVars列表 對於每個varGroup元素並保持和變量元素的順序, notVars清單。謝謝代碼重新分解不會在末尾給出相同的結果

public static void RemoveDuplicateListElements(List<VarGroup> vgs) { 
     if (vgs == null) { 
      return; 
     } 
     for (VarGroup vg : vgs) { 
      RemoveDuplicateListElements(vg.getOrVars()); 
      if (vg.getAndVars() != null) { 
       for (int x = vg.getAndVars().size()-1 ; x >= 0; x--) { 
        if (vg.getAndVars().get(x) == null 
          || vg.getAndVars().get(x).isEmpty()) 
        { 
         vg.getAndVars().remove(x); 
        } else { 
         for (int y = 0; y < x; y++) { 
          if (vg.getAndVars().get(x).equals(vg.getAndVars().get(y))) { 
           vg.getAndVars().remove(x); 
           break; 
          } 
         } 
        } 
       } 
      } 

      if (vg.getNotVars() != null) { 
       for (int x = vg.getNotVars().size()-1 ; x >= 0; x--) { 
        if (vg.getNotVars().get(x) == null 
          || vg.getNotVars().get(x).isEmpty()) 
        { 
         vg.getNotVars().remove(x); 
        } else {   
         for (int y = 0; y < x; y++) { 
          if (vg.getNotVars().get(x).equals(vg.getNotVars().get(y))) { 
           vg.getNotVars().remove(x); 
           break; 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
public class VarGroup { 
    private List<String> notVars = new ArrayList(); 
    private List<VarGroup> orVars = new ArrayList(); 
    private List<String> andVars = new ArrayList(); 

    public List<VarGroup> getOrVs() { 
     return this.orVars; 
    } 
    public void setOrVars(List<VarGroup> orVars) { 
     this.orVars = orVars; 
    } 
    public List<String> getAndVars() { 
     return this.andVars; 
    } 
    public void setAndVars(List<String> andVars) { 
     this.andVars = andVars; 
    } 
    public List<String> getNotVars() { 
     return this.notVars; 
    } 
    public void setNotVars(List<String> notVars) { 
     this.notVars = notVars; 
    } 
} 

我的重構是在這裏:

public static void RemoveDuplicateListElements(List<VarGroup> vgs) { 
    if (vgs == null) { 
     return; 
    } 
    for (VarGroup vg : vgs) { 
     RemoveDuplicateListElements(vg.getOrVars()); 
     if (vg.getAndVars() != null) { 
      vg.getAndVars().stream().distinct() 
        .filter(andVar -> Objects.nonNull(andVar) || !andVar.isEmpty()) 
        .collect(Collectors.toList()); 
     } 

     if (vg.getNotVars() != null) { 
      vg.getNotVars().stream().distinct() 
        .filter(notVar -> Objects.nonNull(notVar) || !notVar.isEmpty()) 
        .collect(Collectors.toList()); 
     } 
    } 
} 
+1

請編輯該問題,將其限制爲具有足夠詳細信息的特定問題以確定適當的答案。避免一次詢問多個不同的問題。 –

+5

(1)編寫通過原始代碼的測試(2)逐步重構並在每個步驟測試。 – assylias

+1

另請注意,您的流操作不會執行任何操作(您將結果收集到列表中,但忽略返回的值)... – assylias

回答

2

這段代碼在你的重構的方法不會做任何事情:

if (vg.getAndVars() != null) { 
    vg.getAndVars().stream().distinct() 
       .filter(andVar -> Objects.nonNull(andVar) || !andVar.isEmpty()) 
       .collect(Collectors.toList()); 
} 

它只是創建一個從列表中的數據流,過濾流,然後從過濾的流創建一個新列表。但是,這個新名單將立即被廢棄。您應該使用創建的過濾列表,使用setAndVars或使用retainAll修改現有列表。

另外,如果你想使用流和lambdas,那麼使用removeIf怎麼樣?您可以使用Set1)跟蹤重複。簡單的例子:

List<String> lst = new ArrayList<>(Arrays.asList("foo", "bar", "foo", "blub", null)); 
Set<String> seen = new HashSet<>(); 
lst.removeIf(x -> x == null || ! seen.add(x)); 

1)通常你不應該使用具有副作用流的方法。

2

我想你應該提取這裏的一些功能:

public static void removeDuplicateListElements(List<VarGroup> vgs) { 
    if (vgs == null) { 
     return; 
    } 
    for (final VarGroup vg : vgs) { 
     removeDuplicateListElements(vg.getOrVars()); 
     handleVars(vg.getAndVars()); 
     handleVars(vg.getNotVars()); 
    } 
} 

private static void handleVars(final List<String> theVars) { 
    if (theVars != null) { 
     for (int x = theVars.size() - 1; x >= 0; x--) { 
      if (theVars.get(x) == null || theVars.get(x).isEmpty()) { 
       theVars.remove(x); 
      } else { 
       for (int y = 0; y < x; y++) { 
        if (theVars.get(x).equals(theVars.get(y))) { 
         theVars.remove(x); 
         break; 
        } 
       } 
      } 
     } 
    } 
} 

方法使用(的IntelliJ IDEA):

  • 選擇vg.getAndVars()並提取一個變量是
  • 選擇vg.getOrVars()並提取變量因爲它
  • 得到了重複代碼的警告
  • 選擇標記爲複製的第一集團和提取物的方法(接受的IntelliJ提議來代替第二塊)
  • 直列乏在2個第一步驟
  • (加成步驟:一些重命名)萃取
0

它看起來對我這樣的代碼既然你去除在循環列表中的元素將刪除列表

for (int x = vg.getAndVars().size()-1 ; x >= 0; x--) { 
    // ... 
    for (int y = 0; y < x; y++) { 
     if (vg.getAndVars().get(x).equals(vg.getAndVars().get(y))) { 
      vg.getAndVars().remove(x); 
       break; 
      } 
     } 
    } 
} 

的每一個元素,存儲在給定索引的數據可以在循環過程中改變。

0

如果您想刪除重複項並保留順序,爲什麼不使用TreeSet

+0

TreeSet已排序。如果OP使用Set(我同意,這可能是一個好主意),我認爲他們會希望按插入順序排序的LinkedHashSet。 LinkedHashSet將保留列表的原始順序。 – Radiodef

相關問題