2016-06-14 14 views
6

Xem xét mã bên dưới và thực tế là 4 HashSet s được điền ở nơi khác.Làm cách nào để tính toán giao lộ giữa hơn hai HashSets?

Mục đích của tôi là chứa tất cả (các) phần tử phổ biến trong tất cả 4 HashSets.

Câu hỏi của tôi là trước hết, tôi có làm đúng không? Thứ hai, nếu tôi làm đúng, có cách nào tốt hơn để làm điều đó không? Nếu không, thì tôi có giải pháp nào cho vấn đề này?

static Set<String> one=new HashSet<>(); 
static Set<String> two=new HashSet<>(); 
static Set<String> three=new HashSet<>(); 
static Set<String> four=new HashSet<>(); 

private static void createIntersectionQrels() { 
    ArrayList<String> temp = new ArrayList<>(); 
    Set<String> interQrels = new HashSet<>(); 

    temp.addAll(one); 
    one.retainAll(two); 
    interQrels.addAll(one); 
    one.addAll(temp); 
    one.retainAll(three); 
    interQrels.addAll(one); 
    one.addAll(temp); 
    one.retainAll(four); 
    interQrels.addAll(one); 
    one.addAll(temp); 

    interQrels.retainAll(two); 
    interQrels.retainAll(three); 
    interQrels.retainAll(four); 
} 

Trả lời

9

Tôi nghĩ bạn có thể chỉ đơn giản là có thể gọi retainAll() trên tập đầu tiên, bằng cách sử dụng thứ hai, thứ ba, thứ tư và bộ như các thông số:

private static Set<String> getIntersectionSet() { 
    // create a deep copy of one (in case you don't wish to modify it) 
    Set<String> interQrels = new HashSet<>(one); 

    interQrels.retainAll(two);  // intersection with two (and one) 
    interQrels.retainAll(three); // intersection with three (and two, one) 
    interQrels.retainAll(four); // intersection four (and three, two, one) 

    return interQrels; 
} 
+0

Vì vậy, tôi chỉ đang làm quá phản ứng để cư trú tập đầu tiên mỗi khi tôi sử dụng 'retainAll()'? Tôi chỉ lo lắng rằng nếu một số thông tin bị bỏ qua. – lonesome

+0

Nếu một yếu tố thực sự là phổ biến cho cả bốn bộ, thì bạn không cần phải tiếp tục thêm nó (suy nghĩ về điều đó trong một thời điểm). –

+0

Yea, có vẻ đúng. – lonesome

0

Tôi nghĩ cách tốt nhất để xử lý điều này là với Groovy. Tôi biết bạn đã không yêu cầu groovy, nhưng bất cứ lúc nào tôi có thể chuyển đổi tất cả các mã đó thành một dòng, thật khó để cưỡng lại.

println one.intersect(two).intersect(three).intersect(four) 
3

Tôi là một chút mới để Java 8, nhưng này có vẻ khá dễ đọc:

Set<String> intersection = one.stream() 
            .filter(two::contains) 
            .filter(three::contains) 
            .filter(four::contains) 
            .collect(Collectors.toSet()); 

Dưới đây là một thử nghiệm Junit nhanh chóng để thử:

@Test 
public void testIntersectionBetweenSets() { 
    Collection<String> one = new HashSet<>(4); 
    one.add("Larry"); 
    one.add("Mark"); 
    one.add("Henry"); 
    one.add("Andrew"); 
    Set<String> two = new HashSet<>(2); 
    two.add("Mark"); 
    two.add("Andrew"); 
    Set<String> three = new HashSet<>(3); 
    three.add("Mark"); 
    three.add("Mary"); 
    three.add("Andrew"); 
    Set<String> four = new HashSet<>(3); 
    four.add("Mark"); 
    four.add("John"); 
    four.add("Andrew"); 

    Set<String> intersection = one.stream() 
      .filter(two::contains) 
      .filter(three::contains) 
      .filter(four::contains) 
      .collect(Collectors.toSet()); 

    Collection<String> expected = new HashSet<>(2); 
    expected.add("Andrew"); 
    expected.add("Mark"); 
    Assert.assertEquals(expected, intersection); 
} 
+0

Đẹp - nên mặc dù về luồng;) +1 – Chewy

Các vấn đề liên quan