2017-03-11 54 views
1

我可以根據java 8中另一個數組列表中找到的元素來過濾數組列表嗎?整個故事是我從Oracle電子商務套件應用Java 8流如何過濾內容在另一個arrayList中找不到列表?

**EmpID** 
0
003456 
023299 

獲取在職員工的名單,我有一個單獨的文件,其中包含照片與文件名稱EmpID.jpeg

**FileName** 
00123.jpeg 
003456.jpeg 
023299.jpeg   

現在我的目的是比較列表並篩選提供照片的員工以及他們沒有給我的照片。

private ArrayList<String> _IDsFromFile; 
private ArrayList<String> _IDsFromImage; 

     --- 
     --- 

public void compareAndCopy(String fileName){ 

} 
+0

[如何將java.util.List複製到另一個java.util.List中](http://stackoverflow.com/questions/14319732/how-to-copy-a-java-util-list -into-another-java-util-list) –

+0

有沒有這種情況下,你會預計這些集合中的重複?也就是說,您是否曾經擁有ID爲「00123」的另一名員工或者有可能是兩張*圖片,名稱分別爲「00123.jpeg」? – Makoto

回答

7

首先,你應該轉換一個或將這些列表中的另一個列入Set,這樣.contains()檢查是有效的。在List上調用.contains()是一個線性時間操作,這意味着這樣做n次是二次的。

一旦你這樣做了,直接使用.filter()甚至.partitioningBy()來確定兩個列表重疊的位置。

Set<String> imageIdsSet = new HashSet<>(IDsFromImage); 

List<String> overlappingIds = IDsFromFile.stream() 
    .filter(imageIdsSet::contains) 
    .collect(toList()); 

// OR 

Map<Boolean, List<String>> partitionedIds = IDsFromFile.stream() 
    .collect(partitioningBy(imageIdsSet::contains)); 
List<String> overlappingIds = partitionedIds.get(true); 
List<String> missingIds = partitionedIds.get(false); 

你描述,原則上是set operations。 「重疊」ID是兩組ID中的交叉點,而「缺失」ID是差異

Guava在其Sets實用程序中提供了這些操作的高效實現。 (union,intersectiondifferencecomplementOf)。

+0

謝謝你,偉大的工程。 –

5

您可以使用filter API in java 8 Stream來做到這一點。如下面的代碼片段:

import java.util.HashSet; 
import java.util.Set; 
import java.util.stream.Collectors; 

/** 
* @author Shizhz 
*/ 
public class Main { 
    private static Set<String> _IDsFromFile; 
    private static Set<String> _IDsFromImage; 

    static { 
     _IDsFromFile = new HashSet(); 
     _IDsFromFile.add("00123"); 
     _IDsFromFile.add("003456"); 
     _IDsFromFile.add("023299"); 
     _IDsFromFile.add("023300"); 

     _IDsFromImage = new HashSet<>(); 
     _IDsFromImage.add("00123.jpeg"); 
     _IDsFromImage.add("003456.jpeg"); 
     _IDsFromImage.add("023299.jpeg"); 
    } 

    private static Set<String> filterEmployeesWithPhones(Set<String> employeeSet, Set<String> photoSet) { 
     return employeeSet.stream().filter(empId -> photoSet.contains(empId + ".jpeg")).collect(Collectors.toSet()); 
    } 

    public static void main(String[] args) { 
     filterEmployeesWithPhones(_IDsFromFile, _IDsFromImage).forEach(emp -> System.out.println(emp)); 
    } 
} 

會給你的結果:

+2

由於列表確定元素成員資格的O(n)時間,這或多或少是正確的,但不是高性能的。如果你可以使用'Set's,那麼它會非常好。 – Makoto

+1

@Makoto,是的,你是對的,更新我的代碼片段。在這種情況下,我認爲'集合'對'員工'和'電話'集合都可以。謝謝你的建議:-) – shizhz

+0

謝謝你是一個很好的解決方案。亞集將表現良好。尤其是與大量的員工 –

相關問題