01/10/2018, 11:52

Không hiểu về câu lệnh "TreeSet::new" Lambda trong Java

TreeSet::new là tham chiếu đến constructor. Nhưng em không hiểu cụ thể nó như thế nào? ai biết có thể giải thích hộ em được ko??

cụ thể là trong đoạn code này:

public class Main {

    private int anInt;

    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();
        try (
            BufferedReader bufferedInputStream =
                    new BufferedReader(
                            new InputStreamReader(
                                    Main.class.getResourceAsStream("yep.txt")));
            Stream<String> yep = bufferedInputStream.lines();
        )
        {
            System.out.println(Main.class.getResource("yep.txt").toString());
            yep.map(line -> {
                String[] s = line.split(" ");
                Person p = new Person(s[0].trim(), Integer.parseInt(s[1]));
                persons.add(p);
                return p;
            }).forEach(System.out::println);

            Map<Integer, Set<String>> map =
                    persons.stream().
                            collect(Collectors.groupingBy(
                                    Person::getAge, Collectors.mapping(
                                    Person::getName, Collectors.toCollection(TreeSet::new))));

            System.out.println(map);
        }catch(Exception e) {
        }
    }
}

class Person {
    String name;
    int age;

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Nội dung của file:

hoang 20
minh 17
toan 23
tuan 19
khang 55
Hoang 20
Minh 17
Toan 23
Tuan 19
Khang 55

kết quả:

file:/home/eli/IdeaProjects/Yep/out/production/HelloWorld/lambda/yep.txt
lambda.Person@7f63425a
lambda.Person@36d64342
lambda.Person@39ba5a14
lambda.Person@511baa65
lambda.Person@340f438e
lambda.Person@30c7da1e
lambda.Person@5b464ce8
lambda.Person@57829d67
lambda.Person@19dfb72a
lambda.Person@17c68925
{17=[Minh, minh], 19=[Tuan, tuan], 20=[Hoang, hoang], 55=[Khang, khang], 23=[Toan, toan]}

Đỗ Trung Quân viết 14:06 ngày 01/10/2018

Đầu tiên Collectors.groupingBy cho phép bạn tạo một Mapkey của Map chính là đối số đầu tiên là Age.giá trị của key là List các thành phần trong Stream - Name

Bên trong Value của từng Key họ sử dụng Collectors.mapping để map các thành phần tên giống nhau. Nhưng họ muốn xếp theo thứ tự Hoa Thường, nhỏ đến lớn cho nên dùng TreeSet.

Hoang viết 13:58 ngày 01/10/2018

Anh ơi ý em là syntax TreeSet::new nó có nghĩa là gì nếu viết rõ ràng hơn? Vì câu lệnh này hơi khó hiểu đối vs em… Mà ks đâu a ạ. Câu lệnh này em cũng viết được rùi (Y).
Thanks!

Nguyễn Duy Hùng viết 14:07 ngày 01/10/2018

Đoạn code này lấy ở đâu vậy bạn ?

Hoang viết 13:59 ngày 01/10/2018

Mình học trên pluralsight.com bạn ạ. Đây là code của tác giả đã được mình viết lại chút chút . Trên đó có rất nhiều thứ bạn có thể vào tham khảo. https://www.pluralsight.com/

Đỗ Trung Quân viết 14:06 ngày 01/10/2018
:: 

Trong java 8 gọi đó là Method Reference nghĩa là tham chiếu đến hàm (method)

Giả sử em có 1 class Number và bên trong nó là 1 hàm kiểm tra tổng 2 số có lớn hơn 50 không.

class Numbers {
  public static boolean isMoreThanFifty(int n1, int n2) {
    return (n1 + n2) > 50;
  }

  public static List<Integer> findNumbers(
    List<Integer> l, BiPredicate<Integer, Integer> p) {
      List<Integer> newList = new ArrayList<>();
      for(Integer i : l) {
        if(p.test(i, i + 10)) {
          newList.add(i);
        }
      }
      return newList;
  }
}

Khi đó em có thể call method so sánh trên bằng cách thông thường

List<Integer> list = Arrays.asList(12,5,45,18,33,24,40);
// Using an anonymous class
findNumbers(list, new BiPredicate<Integer, Integer>() {
  public boolean test(Integer i1, Integer i2) {
    return Numbers.isMoreThanFifty(i1, i2);
  }
});

Hay sử dụng lambda

// Using a lambda expression
findNumbers(list, (i1, i2) -> Numbers.isMoreThanFifty(i1, i2));

Và cách ngắn hơn là dùng Method Reference

findNumbers(list, Numbers::isMoreThanFifty);

Như vậy có thể hiểu TreeSet ở đây là tên 1 class và new là 1 hàm bên trong class TreeSet. Và đó là hàm tạo

TreeSet(Collection<? extends E> c)
Constructs a new tree set containing the elements in the specified collection, sorted according to the natural ordering of its elements.

TreeSet(Comparator<? super E> comparator)
Constructs a new, empty tree set, sorted according to the specified comparator.

TreeSet(SortedSet<E> s)
Constructs a new tree set containing the same elements and using the same ordering as the specified sorted set.

Còn bên trong TreeSet(Collection<? extends E> c) nó làm gì tiếp thì em phải tự tìm hiểu TreeSet implement và Comparator

Hoang viết 13:54 ngày 01/10/2018

Cảm ơn anh nhiều! em hiểu rùi ạ

Bài liên quan
0