2009-07-08 27 views
5

Tôi là một người .NET. Ban đầu, làm việc trong Java gần đây, và tìm thấy tôi thực sự thiếu LINQ to Objects, đặc biệt để thực hiện lọc chống lại các bộ sưu tập.Quaere - Bất kỳ ai sử dụng nó chưa? (LINQ to Objects for Java)

Một vài người ở đây trên Stack Overflow đã trả lời "LINQ cho Java?" câu hỏi với một từ duy nhất:

Quaere

Tuy nhiên, trên trang web đó nêu rõ "Pre-Beta", và không hề được cam kết để mã của họ trong hơn một năm, vì vậy tôi đoán dự án là khá nhiều người chết.

Có ai thực sự đang sử dụng tính năng này và/hoặc có bất kỳ trải nghiệm nào với nó không?

Câu trả lời phổ biến thứ hai dường như là "sử dụng Google Collections". Đây có phải là cách Java thích hợp nhất không?

Cheers

Marty

+1

Đối với LINQ đối tượng kiểm tra github.com/nicholas22/jpropel-light, ví dụ thực: chuỗi mới [] {"james", "john", "john", "eddie"} .where (startsWith ("j")) .toList(). khác biệt(); –

Trả lời

5

Bạn có thể chọn các mục trong một bộ sưu tập (và nhiều hơn nữa) một cách dễ đọc hơn bằng cách sử dụng thư viện lambdaj

http://code.google.com/p/lambdaj/

+0

+1 Có vẻ rất đẹp, cảm ơn liên kết. – skaffman

+0

Đúng, đã sử dụng lambaj một lúc kể từ khi đăng câu hỏi (nhưng quên cập nhật.) Cảm ơn bạn đã liên kết - đó thực sự là một dự án tuyệt vời. –

+1

Cá nhân tôi không hiểu sự cường điệu xung quanh LINQ, đặc biệt là sau khi nhìn thấy những gì LambdaJ làm (và làm thế nào!). Chắc chắn đáng giá +1. – Esko

1

Đối với đơn giản LINQ to Objects, tốt nhất tôi nghĩ rằng có thể được thực hiện trong Java là một cái gì đó như thế này:

Vector<Integer> numbers = new Vector<Integer>(); 

numbers.add(42); 
numbers.add(3); 
numbers.add(16); 
numbers.add(92); 
numbers.add(9); 

Iterable<Integer> filtered = new Where<Integer>(numbers) { 
    protected boolean predicate(Integer i) { return i > 10; } 
}; 

Iterable<String> converted = new Select<Integer, String>(filtered) { 
    protected String select(Integer i) { return i.toString(); } 
}; 

for (final String str : converted) 
    System.out.println(str); 

Lưu ý rằng tôi đã không nhận được WhereSelect chuỗi với nhau trong một biểu thức. Tôi có thể chèn định nghĩa của filtered vào một nơi nó được sử dụng, nhưng điều đó có lẽ sẽ làm cho nó (thậm chí) ít có thể đọc được. Các vấn đề là thiếu các phương pháp mở rộng và lambdas. Gần nhất chúng ta có thể nhận được lambdas là bởi những tuyên bố lớp ẩn danh. Chúng có thể tham chiếu đến các đối tượng có tên trong phạm vi kèm theo, nhưng chỉ có final s, vì vậy chúng không thể đột biến bất kỳ thứ gì (không giống lambdas trong C#).

Cú pháp cực kỳ dài dòng là một nỗi đau. Mọi người thường đề xuất rằng Java nên cung cấp một cú pháp đơn giản hơn cho các trường hợp chỉ có một phương thức trừu tượng (hoặc giao diện), và do đó không cần đưa ra khai báo tên hoặc kiểu cho những gì bạn muốn ghi đè. Sau đó, có một thực tế là không có suy luận kiểu, và không có cách rõ ràng để cung cấp nó trên constructors lớp chung vì new Select(filtered) đã có nghĩa là cái gì khác.

Việc triển khai cho SelectWhere là:

abstract class Select<TSource, TResult> implements Iterable<TResult> 
{ 
    private Iterable<TSource> _source; 

    public Select(Iterable<TSource> source) 
     { _source = source; } 

    private class Iter implements Iterator<TResult> 
    { 
     private Iterator<TSource> _i; 

     public Iter() { _i = _source.iterator(); } 

     public void remove() 
      { _i.remove(); } 

     public boolean hasNext() 
      { return _i.hasNext(); } 

     public TResult next() 
      { return select(_i.next()); } 
    } 

    protected abstract TResult select(TSource source); 

    public Iterator<TResult> iterator() 
     { return new Iter(); } 
} 

abstract class Where<TSource> implements Iterable<TSource> 
{ 
    private Iterable<TSource> _source; 

    public Where(Iterable<TSource> source) 
     { _source = source; } 

    private class Iter implements Iterator<TSource> 
    { 
     private Iterator<TSource> _i; 
     private TSource _cachedNext; 
     private boolean _hasCachedNext; 

     public Iter() 
     { 
      _i = _source.iterator(); 
      fetch(); 
     } 

     public void remove() 
      { _i.remove(); } 

     public boolean hasNext() 
      { return _hasCachedNext; } 

     public TSource next() 
     { 
      TSource result = _cachedNext; 
      fetch(); 
      return result; 
     } 

     private void fetch() 
     { 
      _hasCachedNext = false; 

      while (_i.hasNext()) 
      { 
       _cachedNext = _i.next(); 
       if (predicate(_cachedNext)) 
       { 
        _hasCachedNext = true; 
        return; 
       } 
      } 
     } 
    } 

    protected abstract boolean predicate(TSource source); 

    public Iterator<TSource> iterator() 
     { return new Iter(); } 
} 
3

Quaere là ở một vị trí tiên phong với LINQ trong Java, nhưng không phải là typesafe, một trong những điểm chính của LINQ.

Querydsl là loại an toàn và hỗ trợ lọc, sắp xếp và chiếu Bộ sưu tập.

Nó cũng hỗ trợ các hoạt động trên các chương trình phụ trợ JPA/Hibernate, JDO và SQL.

Cú pháp tương tự như SQL với sự khác biệt về thứ tự cơ bản là từ-danh sách-đâu.

Tôi là người duy trì Querydsl, vì vậy câu trả lời này là thiên vị.

1

SBQL4J có thể đáp ứng Yêu cầu của bạn. Đó là loại mở rộng an toàn cho ngôn ngữ Java, nhưng nó cũng tương thích 100% với Java 6 VM. SBQL4J cung cấp các khả năng tương tự như LINQ-to-objects.

ví dụ truy vấn Daniel nên như thế này:

Vector<Integer> numbers = new Vector<Integer>(); 

numbers.add(42); 
numbers.add(3); 
numbers.add(16); 
numbers.add(92); 
numbers.add(9); 

Iterable<Integer> filtered = #{ numbers as n where n > 10 }; 

Iterable<String> converted = #{ numbers.toString() }; 

for (final String str : converted) 
    System.out.println(str); 

Có khoảng 35 nhà khai thác của ngôn ngữ truy vấn, bao gồm lựa chọn, chiếu, đặt hàng, các nhà khai thác số học, tập hợp, bắc cầu đóng cửa, phạm vi, vv

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