Trong C++, tôi có thể sử dụng find_if
với biến vị ngữ để tìm một phần tử trong vùng chứa. Có cái gì đó như thế trong Java? Phương thức contains
trên bộ sưu tập sử dụng bằng và không thể tham số hóa.Có điều gì đó giống như find_if trong Java không?
Trả lời
Bạn có thể sử dụng Predicate từ Google Collections. Đây là tutorial và một ví dụ từ nó:
final Predicate<Car> expensiveCar = new Predicate<Car>() {
public boolean apply(Car car) {
return car.price > 50000;
}
}
List<Car> cars = Lists.newArrayList();
cars.add(new Car("Ford Taurus", 20000));
cars.add(new Car("Tesla", 90000));
cars.add(new Car("Toyota Camry", 25000));
cars.add(new Car("McClaren F1", 600000));
final List<Car> premiumCars =
Lists.immutableList(Iterables.filter(cars, expensiveCar));
Bạn cũng có thể xem chủ đề này: What is the best way to filter a Collection?
'Iterables.find' (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#find%28java.lang.Iterable,%20com.google. common.base.Predicate% 29) sẽ chỉ cung cấp phần tử khớp đầu tiên. –
@Matthew Flaschen: vâng, nếu chúng ta chỉ cần nhận được ít nhất 1 mục tương ứng thì 'Iterables.find' sẽ là giải pháp tốt nhất. – Roman
Tôi nghĩ rằng bạn đang sử dụng ảnh chụp nhanh trước khi phát hành của Google Bộ sưu tập! Nếu bạn muốn sao chép các iterable lọc vào một danh sách bất biến (như trái ngược với chỉ looping thông qua nó trực tiếp), sử dụng ImmutableList.copyOf(). –
Bạn có thể sử dụng CollectionUtils.select từ Apache Commons.
Ví dụ, C sau ++ mã
bool isOdd (int i) {
return i % 2 != 0;
}
...
vector<int> myvector;
vector<int>::iterator it;
myvector.push_back(10);
myvector.push_back(25);
myvector.push_back(40);
myvector.push_back(55);
it = find_if (myvector.begin(), myvector.end(), isOdd);
cout << "The first odd value is " << *it << endl;
có thể được viết bằng Java như,
List<Integer> myList = Arrays.asList(10, 25, 40, 55);
List<Integer> oddNums = (List<Integer>) CollectionUtils.select(myList,
new Predicate<Integer>() {
public boolean apply(Integer i) {
return i % 2 != 0;
}
}
);
System.out.println("The first odd value is "+oddNums.get(0));
Xin lưu ý rằng, không giống như trong C++ ví dụ, điều này sẽ tạo ra một danh sách mới của các yếu tố thỏa mãn vị từ được chỉ định.
EDIT:
Như Matthew Flaschen đã gợi ý trong một chú thích dưới đây, CollectionUtils.find thậm chí còn gần gũi hơn với những gì bạn cần. Như vậy, với find
, mã trên có thể được viết lại như sau:
List<Integer> myList = Arrays.asList(10, 25, 40, 55);
Integer firstOdd = (Integer) CollectionUtils.find(myList,
new Predicate<Integer>() {
public boolean apply(Integer i) {
return i % 2 == 1;
}
}
);
System.out.println("The first odd value is "+firstOdd);
CollectionUtils.find (http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html#find%28java.util.Collection,%20org.apache.commons.collections.Predicate% 29) thậm chí còn gần hơn; nó chỉ trả về phần tử khớp đầu tiên. –
@Matthew: Cảm ơn. Đã cập nhật câu trả lời để bao gồm điều đó. – missingfaktor
Không bao giờ sử dụng bộ sưu tập apache trừ khi bạn đã có trong java 1.4.2 hoặc thấp hơn. – KitsuneYMG
Bằng cách sử dụng lambdaj bạn có thể dễ dàng lọc một bộ sưu tập java một cách rất dễ đọc. Ví dụ: tuyên bố sau:
select(persons, having(on(Person.class).getAge(), greaterThan(30)));
chọn tất cả những người trong danh sách của bạn có hơn 30 năm.
Vấn đề là sử dụng phương thức như find_if sẽ làm cho mã đơn giản hơn để viết và dễ đọc hơn. Tuy nhiên, IMHO Java không cho vay chính nó với ký pháp chức năng và phần lớn thời gian nó rõ ràng và đơn giản hơn để chỉ viết một vòng lặp tự nhiên. tức là mã ngắn hơn và không yêu cầu kiến thức về thư viện mà hầu hết mọi người không sử dụng. Nếu chức năng này được xây dựng và hỗ trợ Java đóng cửa (như nó xuất hiện Java 7 sẽ) sau đó sử dụng vị từ và phương pháp chức năng sẽ có ý nghĩa hơn. Một số đo độ phức tạp là đếm số biểu tượng (đếm mở/đóng dấu ngoặc đơn) Sử dụng biện pháp phức tạp này, hầu hết các giải pháp dựa trên vị ngữ có nhiều ký hiệu hơn và có thể phức tạp và khó khăn hơn cho các nhà phát triển để đọc/duy trì .
Trong ví dụ được đưa ra bởi @Roman, có 15 ký hiệu. Trong ví dụ vòng lặp, có 10 biểu tượng.
List<Car> premiumCars = new ArrayList();
for(Car car: cars)
if(car.price > 50000)
premiumCars.add(car);
Trong ví dụ bằng @Mario Fuscom, có 9 ký hiệu, trong ví dụ sau có 9 ký hiệu. Tuy nhiên, không có chức năng phi tiêu chuẩn nào được yêu cầu và bất kỳ ai biết Java có thể đọc/duy trì nó.
List peopleOver30 = new ArrayList();
for(Person person: people)
if(person.age > 30)
peopleOver30.add(person);
Lấy ví dụ cuối cùng từ @Rahul G - Tôi ghét Unicorns, có 13 ký hiệu. Trong ví dụ vòng lặp, có 8 ký hiệu.
Integer firstOdd = null;
for(int i: myList)
if(i % 2 == 1) {
firstOdd = i;
break;
}
Lập trình chức năng có thể có ý nghĩa hơn với bạn vì đó là nền tảng phát triển của bạn, nhưng điều này không có nghĩa là cách tự nhiên hoặc đơn giản nhất để thể hiện điều này trong Java. Java 7 có thể thay đổi điều này ....
Phản hồi tốt Peter. Tôi đã thử sử dụng một phong cách chức năng trong Java, và cũng đã phát hiện ra nó làm cho mã phức tạp hơn, và khó hiểu hơn. –
- 1. Có điều gì đó giống như Codecademy cho Java
- 2. Có điều gì đó giống như __LINE__ trong Verilog không?
- 3. Có điều gì đó giống như bpython cho Ruby không?
- 4. Có điều gì đó giống như .NET của T4 cho Java không?
- 5. Có điều gì đó giống như Ghi chú chú thích trong java?
- 6. Có điều gì đó giống như ZenTest/Autotest cho Java và JUnit
- 7. Có điều gì đó giống như MOVE-CORRESPONDING IGNORING INITIALS trong ABAP không?
- 8. Có điều gì đó giống như TimeSpan trong phát triển Android không?
- 9. Có điều gì đó giống như printf trong Action Script 3 không?
- 10. Có bash gì đó giống như perls __DATA__ không?
- 11. Có gì giống như Java Quartz trong ruby không?
- 12. Có điều gì giống như JRebel cho .NET không?
- 13. Có cái gì đó giống như Python 'với' trong C#?
- 14. Có điều gì đó giống như Snoop (WPF) hoặc FireBug (ASP.NET) cho Windows Forms không?
- 15. Có điều gì đó giống như "Di tích mới" cho ứng dụng Perl không?
- 16. Có điều gì giống như pngcrush cho GIF không?
- 17. Có điều gì giống như instanceOf (Class <?> c) trong Java không?
- 18. Có điều gì cho Python giống như readability.js không?
- 19. Có điều gì giống như chỉ mục pmax không?
- 20. Có điều gì giống như xuất khẩu Python không?
- 21. Có cái gì đó giống như Incanter cho Haskell?
- 22. Có điều gì giống như con trỏ trong Lúa?
- 23. Có điều gì đó tương tự như mini-mvc-profiler cho Java không?
- 24. Có cái gì đó giống như `last` cho` map`?
- 25. Có cái gì đó giống như WMI cho Linux?
- 26. Java có thể làm điều gì đó như thể loại trong Mục tiêu C không?
- 27. Có một cái gì đó giống như Sprocket tồn tại cho Java
- 28. Có điều gì đó như là 'quá trừu tượng' không?
- 29. Có điều gì đó giống như IList.IndexOf() nhưng trên IEnumerable <T>?
- 30. Có điều gì đó giống như trang trí python cho C#?
Sự cống hiến là những gì đến với tâm chk http://commons.apache.org/collections/api-2.1.1/org/apache/commons/collections/class-use/Predicate .html – Narayan
Ngoài ra, hãy xem http://code.google.com/p/google-collections, đặc biệt là các giao diện vị ngữ và chức năng. – gpampara