2015-12-07 21 views
5

trường hợp của tôi là:Tìm yếu tố phù hợp trong 2 danh sách sử dụng java 8 dòng

class Person { 
    String id ; 
    String name; 
    String age; 
} 
List<Person> list1 = {p1,p2, p3}; 
List<Person> list2 = {p4,p5, p6}; 

Tôi muốn biết nếu có người trong list1 có cùng tên và tuổi tác trong list2 nhưng không nhớ về id .

Cách tốt nhất và nhanh nhất là gì?

+0

trong trường hợp của tôi, bằng không có thể được overrided – TNN

Trả lời

3

Xác định chính bạn một đối tượng khóa giữ và so sánh các thuộc tính mong muốn.Trong trường hợp đơn giản này, bạn có thể sử dụng một danh sách nhỏ trong khi mỗi chỉ mục tương ứng với một thuộc tính. Đối với trường hợp phức tạp hơn, bạn có thể sử dụng một Map (sử dụng tên thuộc tính như phím) hoặc một lớp chuyên dụng:

Function<Person,List<Object>> toKey=p -> Arrays.asList(p.getName(), p.getAge()); 

Có như vậy một chức năng lập bản đồ. bạn có thể sử dụng giải pháp đơn giản:

list1.stream().map(toKey) 
    .flatMap(key -> list2.stream().map(toKey).filter(key::equals)) 
    .forEach(key -> System.out.println("{name="+key.get(0)+", age="+key.get(1)+"}")); 

có thể dẫn đến hiệu suất kém khi bạn có danh sách khá lớn. Khi bạn có danh sách lớn (hoặc không thể dự đoán kích thước của chúng), bạn nên sử dụng một trung gian Set để đẩy nhanh tiến độ tra cứu (thay đổi phức tạp thời gian của nhiệm vụ O(n²)-O(n)):

list2.stream().map(toKey) 
    .filter(list1.stream().map(toKey).collect(Collectors.toSet())::contains) 
    .forEach(key -> System.out.println("{name="+key.get(0)+", age="+key.get(1)+"}")); 

Trong ví dụ trên, mỗi phù hợp được in. Nếu bạn chỉ quan tâm đến việc liệu một trận đấu như vậy tồn tại, bạn có thể sử dụng một trong hai:

boolean exists=list1.stream().map(toKey) 
    .anyMatch(key -> list2.stream().map(toKey).anyMatch(key::equals)); 

hoặc

boolean exists=list2.stream().map(toKey) 
    .anyMatch(list1.stream().map(toKey).collect(Collectors.toSet())::contains); 
0

Bạn cần phải lặp qua hai danh sách và so sánh các bản ghi chú.

for(Person person1 : list1) { 
    for(Person person2 : list2) { 
     if(person1.getName().equals(person2.getName()) && 
       person1.getAge().equals(person2.getAge())) { 
      //your code 
     } 
    } 
} 
+0

cần java8 tốt hơn stream way :) – TNN

7

Cách đơn giản để thực hiện điều đó là ghi đè equalshashCode. Kể từ khi tôi giả định sự bình đẳng giữa Person cũng phải xem xét lĩnh vực id, bạn có thể quấn trường hợp này thành một PersonWrapper mà sẽ thực hiện đúng equalshashCode (tức là chỉ kiểm tra các lĩnh vực nameage):

class PersonWrapper { 

    private Person person; 

    private PersonWrapper(Person person) { 
     this.person = person; 
    } 

    public static PersonWrapper wrap(Person person) { 
     return new PersonWrapper(person); 
    } 

    public Person unwrap() { 
     return person; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null || getClass() != obj.getClass()) { 
      return false; 
     } 
     PersonWrapper other = (PersonWrapper) obj; 
     return person.name.equals(other.person.name) && person.age.equals(other.person.age); 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + person.name.hashCode(); 
     result = prime * result + person.age.hashCode(); 
     return result; 
    } 

} 

Với ví dụ một lớp, sau đó bạn có thể có những điều sau đây:

Set<PersonWrapper> set2 = list2.stream().map(PersonWrapper::wrap).collect(toSet()); 

boolean exists = 
    list1.stream() 
     .map(PersonWrapper::wrap) 
     .filter(set2::contains) 
     .findFirst() 
     .isPresent(); 

System.out.println(exists); 

mã này chuyển đổi thành một list2Set người quấn. Mục tiêu của việc có một Set là có hoạt động contains liên tục để có hiệu suất tốt hơn.

Sau đó, list1 được lọc. Mỗi phần tử được tìm thấy trong set2 được giữ lại và nếu có một phần tử còn lại (có nghĩa là, nếu findFirst() trả lại một không trống Optional), nó có nghĩa là một phần tử đã được tìm thấy.

+0

trong trường hợp của tôi, bằng không thể ghi đè – TNN

+4

@TodorNeykov Đó là những gì tôi đoán và tôi đã tạo một lớp tùy chỉnh với 'equals' được triển khai, xem câu trả lời của tôi. – Tunaki

+0

hm đẹp, nhưng vẫn còn nặng .. – TNN

2

Nếu bạn không quan tâm đến trường id, thì bạn có thể sử dụng phương thức equals để giải quyết vấn đề này.

Dưới đây là đoạn code Person lớp

public class Person { 
    private String id ; 
    private String name; 
    private String age; 

    @Override 
    public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    Person sample = (Person) o; 

    if (!name.equals(sample.name)) return false; 
    return age.equals(sample.age); 

    } 

    @Override 
    public int hashCode() { 
    int result = name.hashCode(); 
    result = 31 * result + age.hashCode(); 
    return result; 
    } 
} 

Bây giờ, bạn có thể sử dụng dòng để có được những ngã tư như vậy. common sẽ chứa tất cả các đối tượng Person trong đó nameage giống nhau.

List<Person> common = list1 
     .stream() 
     .filter(list2::contains) 
     .collect(Collectors.toList()); 
+0

trong trường hợp của tôi, bằng không thể bị ghi đè – TNN

1

này sẽ làm việc:

class PresentOrNot {boolean isPresent = false;}; 
final PresentOrNot isPresent = new PresentOrNot(); 
l1.stream().forEach(p -> { 
    isPresent.isPresent = isPresent.isPresent || l2.stream() 
     .filter(p1 -> p.name.equals(p1.name) && p.age.equals(p1.age)) 
     .findFirst() 
     .isPresent(); 
}); 
System.err.println(isPresent.isPresent); 

Kể từ forEach() mất tiêu dùng, chúng tôi không có cách nào trở về và PresentOrNot {} là một cách giải quyết. Ngoài: Nơi didi bạn nhận được một yêu cầu như vậy :)

2

brute force, nhưng tinh khiết giải pháp java 8 sẽ là thế này:

boolean present = list1 
     .stream() 
     .flatMap(x -> list2 
      .stream() 
      .filter(y -> x.getName().equals(y.getName())) 
      .filter(y -> x.getAge().equals(y.getAge())) 
      .limit(1)) 
     .findFirst() 
     .isPresent(); 

Ở đây, flatMap được sử dụng để tham gia 2 danh sách. limit được sử dụng vì chúng tôi chỉ quan tâm đến trận đấu đầu tiên, trong trường hợp đó, chúng tôi không cần phải đi xa hơn nữa.

1
<h3>Find List of Object passing String of Array Using java 8?</h3> 
[Faiz Akram][1] 
    <pre> 
    public class Student { 
     private String name; 
     private Integer age; 
     public Student(String name, Integer age) { 
      super(); 
      this.name = name; 
      this.age = age; 
     } 
     public String getName() { 
      return name; 
     } 
     public void setName(String name) { 
      this.name = name; 
     } 
     public Integer getAge() { 
      return age; 
     } 
     public void setAge(Integer age) { 
      this.age = age; 
     } 
    } 
    </pre> 
    // Main Class 
    <pre> 
    import java.util.ArrayList; 
    import java.util.Arrays; 
    import java.util.List; 
    import java.util.stream.Collectors; 
    public class JavaLamda { 
     public static void main(String[] k) 
     { 
     List<Student> stud = new ArrayList<Student>(); 
     stud.add(new Student("Faiz", 1)); 
     stud.add(new Student("Dubai", 2)); 
     stud.add(new Student("Akram", 5)); 
     stud.add(new Student("Rahul", 3)); 
     String[] name= {"Faiz", "Akram"}; 
     List<Student> present = Arrays.asList(name) 
       .stream() 
       .flatMap(x -> stud 
        .stream() 
        .filter(y -> x.equalsIgnoreCase(y.getName()))) 
       .collect(Collectors.toList()); 
     System.out.println(present); 
     } 
    } 
    </pre> 
    OutPut //[[email protected], [email protected]] 


    [1]: http://faizakram.com/blog/find-list-object-passing-string-array-using-java-8/ 
0
public static void main(String[] args) { 
    OTSQuestions ots = new OTSQuestions(); 

    List<Attr> attrs = ots.getAttrs(); 
    List<String> ids = new ArrayList<>(); 
    ids.add("101"); 
    ids.add("104"); 
    ids.add("102"); 

    List<Attr> finalList = attrs.stream().filter(
      attr -> ids.contains(attr.getId())) 
      .collect(Collectors.toList()); 
} 

public class Attr { 
    private String id; 
    private String name; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

private List<Attr> getAttrs() { 
    List<Attr> attrs = new ArrayList<>(); 
    Attr attr = new Attr(); 
    attr.setId("100"); 
    attr.setName("Yoga"); 
    attrs.add(attr); 

    Attr attr1 = new Attr(); 
    attr1.setId("101"); 
    attr1.setName("Yoga1"); 
    attrs.add(attr1); 

    Attr attr2 = new Attr(); 
    attr2.setId("102"); 
    attr2.setName("Yoga2"); 
    attrs.add(attr2); 

    Attr attr3 = new Attr(); 
    attr3.setId("103"); 
    attr3.setName("Yoga3"); 
    attrs.add(attr3); 

    Attr attr4 = new Attr(); 
    attr4.setId("104"); 
    attr4.setName("Yoga4"); 
    attrs.add(attr4); 

    return attrs; 
} 
Các vấn đề liên quan