📜 ⬆️ ⬇️

LINQ for Java: LambdaJ

How often have you seen or written the same few lines of code that are constantly used together to solve the same problem? Take, for example, brute force or sorting (some manipulation) of collections. Programmers have to write such code sections every day. Of course, there are various IDEs in which you can use snippets and templates. Nevertheless, such constructions clutter up the code, making it more suitable for processing by a computer, and not for the programmer's perception.

This is where the LambdaJ library comes to our rescue . Its purpose is to simplify the process of working with collections in order to reduce errors in the code and increase its readability by implementing some functional programming techniques without neglecting the static typing of data. The latter fact is extremely important, since static typing is an advantage of the language, which significantly increases the reliability of the code.

Consider an example of using LambdaJ. Find the age of the youngest buyer, who made a purchase of more than 50'000.
')
Classic (iterative) method:
int age = Integer.MAX_VALUE;
for (Sale sale : sales) {
if (sale.getCost() > 50000.00) {
int buyerAge = sale.getBuyer().getAge();
if (buyerAge < age)
age = buyerAge;
}
}


LambdaJ method:
int age = min(forEach( select (sales, having(
on(Sale. class ).getCost(), greaterThan(50000.00)).getBuyer()))),
on(Person. class ).getAge());



Functionality



From the above example, it is clear that the library provides the programmer with a kind of DSL for working with collections. Domains in this case are java-collections, and language constructs are statically imported methods of the corresponding classes of the LambdaJ library.

So what can LambdaJ do? The list of features is approximately as follows:
Here you can add work with closures (although, in my opinion, it’s better to wait for Java 7 here).


Examples



Filtration

List <Integer> biggerThan3 = filter(greaterThan(3), asList(1, 2, 3, 4, 5));
List <Person> oldFriends = filter(having(on(Person. class ).getAge(), greaterThan(30)), meAndMyFriends);

Aggregation

int totalAge = sum(meAndMyFriends, on(Person. class ).getAge());

Getting properties

List <Integer> lengths = convert(strings, new PropertyExtractor( "length" ));
List <Integer> ages = extract(persons, on(Person. class ).getAge());

Indexing

Map< String , Person> personsByName = index(persons, on(Person. class ).getFirstName());

Sorting

List <Person> sorted = sort(persons, on(Person. class ).getAge());

Grouping

Group<Person> group = group(meAndMyFriends, by(on(Person. class ).getAge()));
Group<Person> group29aged = group.findGroup( "29" );


Performance



As you know, the price for convenience is performance. In the case of LambdaJ, overhead averages 2.5 times [ * ]. This is definitely sad. However, if the manipulation of collections takes an insignificant part of the processor time of your application, then the advantages from the convenience of work can significantly outweigh the minus overhead.


PS


This article is a free translation of arbitrary parts of the official LambdaJ Wiki . More information can be found there.

Source: https://habr.com/ru/post/118041/


All Articles