Sublist starting with a certain object - java

I have a list of objects and I want to iterate through the sublist starting with the object that meets a certain criterion.
(Concretely, the list of declared fields for a class, starting with field such-and-such, known by name not by integer index.)
Obviously one solution would be to iterate through the entire list, setting a flag when the particular object has been found, but it occurs to me to wonder whether Java 8 with its improved support for higher-order programming, provides a more elegant way to do it.
What's the most elegant/idiomatic way to do this in Java 8? (Performance isn't a consideration; the code in question will only be run once per program execution.)

It seems that you want the indexOf method to act like as a predicate, where you can give a custom property to tell whether you find the first object that satisfies it.
It can be done using an helper method.
static <T> List<T> getSubList(List<T> list, Predicate<T> pred){
return list.subList(list.indexOf(list.stream().filter(pred).findFirst().get()), list.size());
}
What it does is:
get a Stream<T> from the list
apply a filter to it
find the first element that satisfied the given predicate
get the object in the resulting Optional<T> calling get()
use indexOf on the list to get the index of this object
return a sublist of the original list
Then you can call it like;
List<MyClass> subList = getSubList(list, o -> o.b.startsWith("10"));
For a small example, here's how you can take a sublist from the first object where its String value starts with a 10 until the end of the list.
public class Test {
public static void main(String[] args) {
List<MyClass> list = new ArrayList<>();
for(int i = 0; i < 15; i++){
list.add(new MyClass(i, String.valueOf(i)));
}
System.out.println(getSubList(list, o -> o.s.startsWith("10"))); //[MyClass [a=10, b=10], MyClass [a=11, b=11], MyClass [a=12, b=12], MyClass [a=13, b=13], MyClass [a=14, b=14]]
}
static <T> List<T> getSubList(List<T> list, Predicate<T> pred){
return list.subList(list.indexOf(list.stream().filter(pred).findFirst().get()), list.size());
}
}
class MyClass {
int i;
String s;
public MyClass(int i,String s){
this.i = i;
this.s = s;
}
#Override
public String toString() {
return "MyClass [i=" + i + ", s=" + s + "]";
}
}
You can add more checks, for example to see if you have a value from the Optional (using isPresent()) you get by calling findFirst, but you have the main idea of how to do it.
Hope it helps! :)

With Guava, you can do
// list is an instance of List<T> from which the sublist is wanted
Iterable<T> sublist = Iterables.skip(list, list.indexOf(certainObject));
However, this does not use any new features of Java 8.

You could:
List<T> list = ...;
Optional<T> first = list.stream()
.filter(f -> f.name.equals("field name"))
.findFirst();
return first.isPresent()
? list.subList(list.indexOf(first))
: Collections.emptyList();
ps: on mobile so not sure it compiles but the general idea should work.

Related

How to create arraylist without one element from another arraylist

I needed to create an arraylist without an element of another arraylist, but I need this new arraylist to keep updating. For example, an element of the old arraylist is removed, also remove in the new one.
But I did not want to remove the element of the two arraylist, only the old one, so as not to have much code
(My method "showPeople" is updated every 1 second)
My code:
ArrayList<Person> personList = new ArrayList<>();
private void method(){
personList.add(new People("Name"))
}
private void showPeople(){
ArrayList<Person> newPersonList =
new ArrayList<>(personList.stream()
.filter(person -> !person.getName().equals("Test"))
.collect(Collectors.toList()))
for (int i = 0; i < newPersonList.size(); i++){
gui.show(newPersonList.get(i).getName());
}
}
The problem is that when I create the new arraylist and remove an item from the old one, the new one does not update
You're making multiple copies of your list; instead, do something like:
List<Person> filterPeople(List<Person> people, #NotNull String name) {
return people.stream()
.filter(person -> !name.equals(person.getName()))
.collect(Collectors.toList());
}
If you're uncomfortable with the lack of guarantees on the the shape of the List, you can be explicit:
.collect(Collectors.toCollection(ArrayList::new));
It's still unclear what you're asking, however. I suggest you provide a minimal, complete, and verifiable example.
If you want the list without the element to keep updating, you can create a view of the list by extending AbstractList.
The API documentation contains instructions as to the methods you would need to override. If you don't want the list to be modifiable through the view, all you need to do is to override the get and size methods:
class ListView extends AbstractList<String> {
private final List<String> delegate; // Initialize in constructor.
public T get(int i) {
int pos = delegate.indexOf("Test");
if (pos < 0 || i < pos) return delegate.get(i);
return delegate.get(i + 1);
}
public int size() {
return delegate.size() - (delegate.contains("Test") ? 1 : 0);
}
}
This will repeatedly search for the "Test" element, because there is no way for the view to know if the delegate list has been updated underneath it.
Here's a handy method:
private static <T> List<T> CopyListWithoutItem(List<T> listToCopy, T itemToNotCopy) {
return listToCopy.stream().filter(item -> !item.equals(itemToNotCopy)).collect(Collectors.toList());
}
You can use that: List<String> elements = list.stream().distinct().collect(Collectors.toList());
That will remove duplicates.

Is there a way to check if an object contains certain data? [duplicate]

I want to filter a java.util.Collection based on a predicate.
Java 8 (2014) solves this problem using streams and lambdas in one line of code:
List<Person> beerDrinkers = persons.stream()
.filter(p -> p.getAge() > 16).collect(Collectors.toList());
Here's a tutorial.
Use Collection#removeIf to modify the collection in place. (Notice: In this case, the predicate will remove objects who satisfy the predicate):
persons.removeIf(p -> p.getAge() <= 16);
lambdaj allows filtering collections without writing loops or inner classes:
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
greaterThan(16)));
Can you imagine something more readable?
Disclaimer: I am a contributor on lambdaj
Assuming that you are using Java 1.5, and that you cannot add Google Collections, I would do something very similar to what the Google guys did. This is a slight variation on Jon's comments.
First add this interface to your codebase.
public interface IPredicate<T> { boolean apply(T type); }
Its implementers can answer when a certain predicate is true of a certain type. E.g. If T were User and AuthorizedUserPredicate<User> implements IPredicate<T>, then AuthorizedUserPredicate#apply returns whether the passed in User is authorized.
Then in some utility class, you could say
public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {
Collection<T> result = new ArrayList<T>();
for (T element: target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
So, assuming that you have the use of the above might be
Predicate<User> isAuthorized = new Predicate<User>() {
public boolean apply(User user) {
// binds a boolean method in User to a reference
return user.isAuthorized();
}
};
// allUsers is a Collection<User>
Collection<User> authorizedUsers = filter(allUsers, isAuthorized);
If performance on the linear check is of concern, then I might want to have a domain object that has the target collection. The domain object that has the target collection would have filtering logic for the methods that initialize, add and set the target collection.
UPDATE:
In the utility class (let's say Predicate), I have added a select method with an option for default value when the predicate doesn't return the expected value, and also a static property for params to be used inside the new IPredicate.
public class Predicate {
public static Object predicateParams;
public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {
Collection<T> result = new ArrayList<T>();
for (T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
public static <T> T select(Collection<T> target, IPredicate<T> predicate) {
T result = null;
for (T element : target) {
if (!predicate.apply(element))
continue;
result = element;
break;
}
return result;
}
public static <T> T select(Collection<T> target, IPredicate<T> predicate, T defaultValue) {
T result = defaultValue;
for (T element : target) {
if (!predicate.apply(element))
continue;
result = element;
break;
}
return result;
}
}
The following example looks for missing objects between collections:
List<MyTypeA> missingObjects = (List<MyTypeA>) Predicate.filter(myCollectionOfA,
new IPredicate<MyTypeA>() {
public boolean apply(MyTypeA objectOfA) {
Predicate.predicateParams = objectOfA.getName();
return Predicate.select(myCollectionB, new IPredicate<MyTypeB>() {
public boolean apply(MyTypeB objectOfB) {
return objectOfB.getName().equals(Predicate.predicateParams.toString());
}
}) == null;
}
});
The following example, looks for an instance in a collection, and returns the first element of the collection as default value when the instance is not found:
MyType myObject = Predicate.select(collectionOfMyType, new IPredicate<MyType>() {
public boolean apply(MyType objectOfMyType) {
return objectOfMyType.isDefault();
}}, collectionOfMyType.get(0));
UPDATE (after Java 8 release):
It's been several years since I (Alan) first posted this answer, and I still cannot believe I am collecting SO points for this answer. At any rate, now that Java 8 has introduced closures to the language, my answer would now be considerably different, and simpler. With Java 8, there is no need for a distinct static utility class. So if you want to find the 1st element that matches your predicate.
final UserService userService = ... // perhaps injected IoC
final Optional<UserModel> userOption = userCollection.stream().filter(u -> {
boolean isAuthorized = userService.isAuthorized(u);
return isAuthorized;
}).findFirst();
The JDK 8 API for optionals has the ability to get(), isPresent(), orElse(defaultUser), orElseGet(userSupplier) and orElseThrow(exceptionSupplier), as well as other 'monadic' functions such as map, flatMap and filter.
If you want to simply collect all the users which match the predicate, then use the Collectors to terminate the stream in the desired collection.
final UserService userService = ... // perhaps injected IoC
final List<UserModel> userOption = userCollection.stream().filter(u -> {
boolean isAuthorized = userService.isAuthorized(u);
return isAuthorized;
}).collect(Collectors.toList());
See here for more examples on how Java 8 streams work.
Use CollectionUtils.filter(Collection,Predicate), from Apache Commons.
"Best" way is too wide a request. Is it "shortest"? "Fastest"? "Readable"?
Filter in place or into another collection?
Simplest (but not most readable) way is to iterate it and use Iterator.remove() method:
Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
Foo foo = it.next();
if( !condition(foo) ) it.remove();
}
Now, to make it more readable, you can wrap it into a utility method. Then invent a IPredicate interface, create an anonymous implementation of that interface and do something like:
CollectionUtils.filterInPlace(col,
new IPredicate<Foo>(){
public boolean keepIt(Foo foo) {
return foo.isBar();
}
});
where filterInPlace() iterate the collection and calls Predicate.keepIt() to learn if the instance to be kept in the collection.
I don't really see a justification for bringing in a third-party library just for this task.
Consider Google Collections for an updated Collections framework that supports generics.
UPDATE: The google collections library is now deprecated. You should use the latest release of Guava instead. It still has all the same extensions to the collections framework including a mechanism for filtering based on a predicate.
Wait for Java 8:
List<Person> olderThan30 =
//Create a Stream from the personList
personList.stream().
//filter the element to select only those with age >= 30
filter(p -> p.age >= 30).
//put those filtered elements into a new List.
collect(Collectors.toList());
Since the early release of Java 8, you could try something like:
Collection<T> collection = ...;
Stream<T> stream = collection.stream().filter(...);
For example, if you had a list of integers and you wanted to filter the numbers that are > 10 and then print out those numbers to the console, you could do something like:
List<Integer> numbers = Arrays.asList(12, 74, 5, 8, 16);
numbers.stream().filter(n -> n > 10).forEach(System.out::println);
I'll throw RxJava in the ring, which is also available on Android. RxJava might not always be the best option, but it will give you more flexibility if you wish add more transformations on your collection or handle errors while filtering.
Observable.from(Arrays.asList(1, 2, 3, 4, 5))
.filter(new Func1<Integer, Boolean>() {
public Boolean call(Integer i) {
return i % 2 != 0;
}
})
.subscribe(new Action1<Integer>() {
public void call(Integer i) {
System.out.println(i);
}
});
Output:
1
3
5
More details on RxJava's filter can be found here.
The setup:
public interface Predicate<T> {
public boolean filter(T t);
}
void filterCollection(Collection<T> col, Predicate<T> predicate) {
for (Iterator i = col.iterator(); i.hasNext();) {
T obj = i.next();
if (predicate.filter(obj)) {
i.remove();
}
}
}
The usage:
List<MyObject> myList = ...;
filterCollection(myList, new Predicate<MyObject>() {
public boolean filter(MyObject obj) {
return obj.shouldFilter();
}
});
How about some plain and straighforward Java
List<Customer> list ...;
List<Customer> newList = new ArrayList<>();
for (Customer c : list){
if (c.getName().equals("dd")) newList.add(c);
}
Simple, readable and easy (and works in Android!)
But if you're using Java 8 you can do it in a sweet one line:
List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());
Note that toList() is statically imported
Are you sure you want to filter the Collection itself, rather than an iterator?
see org.apache.commons.collections.iterators.FilterIterator
or using version 4 of apache commons org.apache.commons.collections4.iterators.FilterIterator
Since java 9 Collectors.filtering is enabled:
public static <T, A, R>
Collector<T, ?, R> filtering(Predicate<? super T> predicate,
Collector<? super T, A, R> downstream)
Thus filtering should be:
collection.stream().collect(Collectors.filtering(predicate, collector))
Example:
List<Integer> oddNumbers = List.of(1, 19, 15, 10, -10).stream()
.collect(Collectors.filtering(i -> i % 2 == 1, Collectors.toList()));
Let’s look at how to filter a built-in JDK List and a MutableList using Eclipse Collections.
List<Integer> jdkList = Arrays.asList(1, 2, 3, 4, 5);
MutableList<Integer> ecList = Lists.mutable.with(1, 2, 3, 4, 5);
If you wanted to filter the numbers less than 3, you would expect the following outputs.
List<Integer> selected = Lists.mutable.with(1, 2);
List<Integer> rejected = Lists.mutable.with(3, 4, 5);
Here’s how you can filter using a Java 8 lambda as the Predicate.
Assert.assertEquals(selected, Iterate.select(jdkList, each -> each < 3));
Assert.assertEquals(rejected, Iterate.reject(jdkList, each -> each < 3));
Assert.assertEquals(selected, ecList.select(each -> each < 3));
Assert.assertEquals(rejected, ecList.reject(each -> each < 3));
Here’s how you can filter using an anonymous inner class as the Predicate.
Predicate<Integer> lessThan3 = new Predicate<Integer>()
{
public boolean accept(Integer each)
{
return each < 3;
}
};
Assert.assertEquals(selected, Iterate.select(jdkList, lessThan3));
Assert.assertEquals(selected, ecList.select(lessThan3));
Here are some alternatives to filtering JDK lists and Eclipse Collections MutableLists using the Predicates factory.
Assert.assertEquals(selected, Iterate.select(jdkList, Predicates.lessThan(3)));
Assert.assertEquals(selected, ecList.select(Predicates.lessThan(3)));
Here is a version that doesn't allocate an object for the predicate, by using the Predicates2 factory instead with the selectWith method that takes a Predicate2.
Assert.assertEquals(
selected, ecList.selectWith(Predicates2.<Integer>lessThan(), 3));
Sometimes you want to filter on a negative condition. There is a special method in Eclipse Collections for that called reject.
Assert.assertEquals(rejected, Iterate.reject(jdkList, lessThan3));
Assert.assertEquals(rejected, ecList.reject(lessThan3));
The method partition will return two collections, containing the elements selected by and rejected by the Predicate.
PartitionIterable<Integer> jdkPartitioned = Iterate.partition(jdkList, lessThan3);
Assert.assertEquals(selected, jdkPartitioned.getSelected());
Assert.assertEquals(rejected, jdkPartitioned.getRejected());
PartitionList<Integer> ecPartitioned = gscList.partition(lessThan3);
Assert.assertEquals(selected, ecPartitioned.getSelected());
Assert.assertEquals(rejected, ecPartitioned.getRejected());
Note: I am a committer for Eclipse Collections.
With the ForEach DSL you may write
import static ch.akuhn.util.query.Query.select;
import static ch.akuhn.util.query.Query.$result;
import ch.akuhn.util.query.Select;
Collection<String> collection = ...
for (Select<String> each : select(collection)) {
each.yield = each.value.length() > 3;
}
Collection<String> result = $result();
Given a collection of [The, quick, brown, fox, jumps, over, the, lazy, dog] this results in [quick, brown, jumps, over, lazy], ie all strings longer than three characters.
All iteration styles supported by the ForEach DSL are
AllSatisfy
AnySatisfy
Collect
Counnt
CutPieces
Detect
GroupedBy
IndexOf
InjectInto
Reject
Select
For more details, please refer to https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach
The Collections2.filter(Collection,Predicate) method in Google's Guava library does just what you're looking for.
This, combined with the lack of real closures, is my biggest gripe for Java.
Honestly, most of the methods mentioned above are pretty easy to read and REALLY efficient; however, after spending time with .Net, Erlang, etc... list comprehension integrated at the language level makes everything so much cleaner. Without additions at the language level, Java just cant be as clean as many other languages in this area.
If performance is a huge concern, Google collections is the way to go (or write your own simple predicate utility). Lambdaj syntax is more readable for some people, but it is not quite as efficient.
And then there is a library I wrote. I will ignore any questions in regard to its efficiency (yea, its that bad)...... Yes, i know its clearly reflection based, and no I don't actually use it, but it does work:
LinkedList<Person> list = ......
LinkedList<Person> filtered =
Query.from(list).where(Condition.ensure("age", Op.GTE, 21));
OR
LinkedList<Person> list = ....
LinkedList<Person> filtered = Query.from(list).where("x => x.age >= 21");
In Java 8, You can directly use this filter method and then do that.
List<String> lines = Arrays.asList("java", "pramod", "example");
List<String> result = lines.stream()
.filter(line -> !"pramod".equals(line))
.collect(Collectors.toList());
result.forEach(System.out::println);
JFilter http://code.google.com/p/jfilter/ is best suited for your requirement.
JFilter is a simple and high performance open source library to query collection of Java beans.
Key features
Support of collection (java.util.Collection, java.util.Map and Array) properties.
Support of collection inside collection of any depth.
Support of inner queries.
Support of parameterized queries.
Can filter 1 million records in few 100 ms.
Filter ( query) is given in simple json format, it is like Mangodb queries. Following are some examples.
{ "id":{"$le":"10"}
where object id property is less than equals to 10.
{ "id": {"$in":["0", "100"]}}
where object id property is 0 or 100.
{"lineItems":{"lineAmount":"1"}}
where lineItems collection property of parameterized type has lineAmount equals to 1.
{ "$and":[{"id": "0"}, {"billingAddress":{"city":"DEL"}}]}
where id property is 0 and billingAddress.city property is DEL.
{"lineItems":{"taxes":{ "key":{"code":"GST"}, "value":{"$gt": "1.01"}}}}
where lineItems collection property of parameterized type which has taxes map type property of parameteriszed type has code equals to GST value greater than 1.01.
{'$or':[{'code':'10'},{'skus': {'$and':[{'price':{'$in':['20', '40']}}, {'code':'RedApple'}]}}]}
Select all products where product code is 10 or sku price in 20 and 40 and sku code is "RedApple".
I wrote an extended Iterable class that support applying functional algorithms without copying the collection content.
Usage:
List<Integer> myList = new ArrayList<Integer>(){ 1, 2, 3, 4, 5 }
Iterable<Integer> filtered = Iterable.wrap(myList).select(new Predicate1<Integer>()
{
public Boolean call(Integer n) throws FunctionalException
{
return n % 2 == 0;
}
})
for( int n : filtered )
{
System.out.println(n);
}
The code above will actually execute
for( int n : myList )
{
if( n % 2 == 0 )
{
System.out.println(n);
}
}
Use Collection Query Engine (CQEngine). It is by far the fastest way to do this.
See also: How do you query object collections in Java (Criteria/SQL-like)?
Using java 8, specifically lambda expression, you can do it simply like the below example:
myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
where for each product inside myProducts collection, if prod.price>10, then add this product to the new filtered list.
Some really great great answers here. Me, I'd like to keep thins as simple and readable as possible:
public abstract class AbstractFilter<T> {
/**
* Method that returns whether an item is to be included or not.
* #param item an item from the given collection.
* #return true if this item is to be included in the collection, false in case it has to be removed.
*/
protected abstract boolean excludeItem(T item);
public void filter(Collection<T> collection) {
if (CollectionUtils.isNotEmpty(collection)) {
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext()) {
if (excludeItem(iterator.next())) {
iterator.remove();
}
}
}
}
}
The simple pre-Java8 solution:
ArrayList<Item> filtered = new ArrayList<Item>();
for (Item item : items) if (condition(item)) filtered.add(item);
Unfortunately this solution isn't fully generic, outputting a list rather than the type of the given collection. Also, bringing in libraries or writing functions that wrap this code seems like overkill to me unless the condition is complex, but then you can write a function for the condition.
https://code.google.com/p/joquery/
Supports different possibilities,
Given collection,
Collection<Dto> testList = new ArrayList<>();
of type,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Filter
Java 7
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property("id").eq().value(1);
Collection<Dto> filtered = query.list();
Java 8
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property(Dto::getId)
.eq().value(1);
Collection<Dto> filtered = query.list();
Also,
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.property(Dto::getId).between().value(1).value(2)
.and()
.property(Dto::grtText).in().value(new string[]{"a","b"});
Sorting (also available for the Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Grouping (also available for the Java 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Joins (also available for the Java 7)
Given,
class LeftDto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
class RightDto
{
private int id;
private int leftId;
private String text;
public int getId()
{
return id;
}
public int getLeftId()
{
return leftId;
}
public int getText()
{
return text;
}
}
class JoinedDto
{
private int leftId;
private int rightId;
private String text;
public JoinedDto(int leftId,int rightId,String text)
{
this.leftId = leftId;
this.rightId = rightId;
this.text = text;
}
public int getLeftId()
{
return leftId;
}
public int getRightId()
{
return rightId;
}
public int getText()
{
return text;
}
}
Collection<LeftDto> leftList = new ArrayList<>();
Collection<RightDto> rightList = new ArrayList<>();
Can be Joined like,
Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
.<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
.on(LeftFyo::getId, RightDto::getLeftId)
.transformDirect(selection -> new JoinedDto(selection.getLeft().getText()
, selection.getLeft().getId()
, selection.getRight().getId())
)
.list();
Expressions
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
My answer builds on that from Kevin Wong, here as a one-liner using CollectionUtils from spring and a Java 8 lambda expression.
CollectionUtils.filter(list, p -> ((Person) p).getAge() > 16);
This is as concise and readable as any alternative I have seen (without using aspect-based libraries)
Spring CollectionUtils is available from spring version 4.0.2.RELEASE, and remember you need JDK 1.8 and language level 8+.
I needed to filter a list depending on the values already present in the list. For example, remove all values following that is less than the current value. {2 5 3 4 7 5} -> {2 5 7}. Or for example to remove all duplicates {3 5 4 2 3 5 6} -> {3 5 4 2 6}.
public class Filter {
public static <T> void List(List<T> list, Chooser<T> chooser) {
List<Integer> toBeRemoved = new ArrayList<>();
leftloop:
for (int right = 1; right < list.size(); ++right) {
for (int left = 0; left < right; ++left) {
if (toBeRemoved.contains(left)) {
continue;
}
Keep keep = chooser.choose(list.get(left), list.get(right));
switch (keep) {
case LEFT:
toBeRemoved.add(right);
continue leftloop;
case RIGHT:
toBeRemoved.add(left);
break;
case NONE:
toBeRemoved.add(left);
toBeRemoved.add(right);
continue leftloop;
}
}
}
Collections.sort(toBeRemoved, new Comparator<Integer>() {
#Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for (int i : toBeRemoved) {
if (i >= 0 && i < list.size()) {
list.remove(i);
}
}
}
public static <T> void List(List<T> list, Keeper<T> keeper) {
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
if (!keeper.keep(iterator.next())) {
iterator.remove();
}
}
}
public interface Keeper<E> {
boolean keep(E obj);
}
public interface Chooser<E> {
Keep choose(E left, E right);
}
public enum Keep {
LEFT, RIGHT, BOTH, NONE;
}
}
This will bee used like this.
List<String> names = new ArrayList<>();
names.add("Anders");
names.add("Stefan");
names.add("Anders");
Filter.List(names, new Filter.Chooser<String>() {
#Override
public Filter.Keep choose(String left, String right) {
return left.equals(right) ? Filter.Keep.LEFT : Filter.Keep.BOTH;
}
});
In my case, I was looking for list with specific field null excluded.
This could be done with for loop and fill the temporary list of objects who have no null addresses.
but Thanks to Java 8 Streams
List<Person> personsList = persons.stream()
.filter(p -> p.getAdrress() != null).collect(Collectors.toList());
#java #collection #collections #java8 #streams
With Guava:
Collection<Integer> collection = Lists.newArrayList(1, 2, 3, 4, 5);
Iterators.removeIf(collection.iterator(), new Predicate<Integer>() {
#Override
public boolean apply(Integer i) {
return i % 2 == 0;
}
});
System.out.println(collection); // Prints 1, 3, 5
An alternative (more lightweight) alternative to Java collection streams is the Ocl.java library, which uses vanilla collections and lambdas: https://github.com/eclipse/agileuml/blob/master/Ocl.java
For example, a simple filter and sum on an ArrayList words
could be:
ArrayList<Word> sel = Ocl.selectSequence(words,
w -> w.pos.equals("NN"));
int total = Ocl.sumint(Ocl.collectSequence(sel,
w -> w.text.length()));
Where Word has String pos; String text; attributes. Efficiency seems similar to the streams option, eg, 10000 words are processed in about 50ms in both versions.
There are equivalent OCL libraries for Python, Swift, etc. Basically Java collection streams has re-invented the OCL operations ->select, ->collect, etc, which existed in OCL since 1998.

How to add prefix to all the elements of List efficiently?

I have a List in which I need to add a prefix in all the elements of my list.
Below is the way I am doing it by iterating the list and then adding it. Is there any other better way to do it? Any one-two liner that can do the same stuff?
private static final List<DataType> DATA_TYPE = getTypes();
public static LinkedList<String> getData(TypeFlow flow) {
LinkedList<String> paths = new LinkedList<String>();
for (DataType current : DATA_TYPE) {
paths.add(flow.value() + current.value());
}
return paths;
}
I need to return LinkedList since I am using some methods of LinkedList class like removeFirst.
I am on Java 7 as of now.
For one liners, use Java 8 Streams :
List<String> paths = DATA_TYPE.stream().map(c -> flow.value() + c.value()).collect(Collectors.toList());
If you must produce a LinkedList, you should use a different Collector.
Your implementation looks ok, but if you want something different, try this:
public static List<String> getData(final TypeFlow flow) {
return new AbstractList<String>() {
#Override
public String get(int index) {
return flow.value()+DATA_TYPE.get(index).value();
}
#Override
public int size() {
return DATA_TYPE.size();
}
};
}
This way you create a "virtual list" which does not actually contains data, but computes it on the fly.

How to have Java method return generic list of any type?

I would like to write a method that would return a java.util.List of any type without the need to typecast anything:
List<User> users = magicalListGetter(User.class);
List<Vehicle> vehicles = magicalListGetter(Vehicle.class);
List<String> strings = magicalListGetter(String.class);
What would the method signature look like? Something like this, perhaps(?):
public List<<?> ?> magicalListGetter(Class<?> clazz) {
List<?> list = doMagicalVooDooHere();
return list;
}
private Object actuallyT;
public <T> List<T> magicalListGetter(Class<T> klazz) {
List<T> list = new ArrayList<>();
list.add(klazz.cast(actuallyT));
try {
list.add(klazz.getConstructor().newInstance()); // If default constructor
} ...
return list;
}
One can give a generic type parameter to a method too. You have correctly deduced that one needs the correct class instance, to create things (klazz.getConstructor().newInstance()).
No need to even pass the class:
public <T> List<T> magicalListGetter() {
return new ArrayList<T>();
}
Another option is doing the following:
public class UserList extends List<User>{
}
public <T> T magicalListGetter(Class<T> clazz) {
List<?> list = doMagicalVooDooHere();
return (T)list;
}
List<User> users = magicalListGetter(UserList.class);
`
Let us have List<Object> objectList which we want to cast to List<T>
public <T> List<T> list(Class<T> c, List<Object> objectList){
List<T> list = new ArrayList<>();
for (Object o : objectList){
T t = c.cast(o);
list.add(t);
}
return list;
}
You can use the old way:
public List magicalListGetter() {
List list = doMagicalVooDooHere();
return list;
}
or you can use Object and the parent class of everything:
public List<Object> magicalListGetter() {
List<Object> list = doMagicalVooDooHere();
return list;
}
Note Perhaps there is a better parent class for all the objects you will put in the list. For example, Number would allow you to put Double and Integer in there.
Something like this
publiс <T> List<T> magicalListGetter(Class<T> clazz) {
List list = doMagicalVooDooHere();
return list;
}
You can simply cast to List and then check if every element can be casted to T.
public <T> List<T> asList(final Class<T> clazz) {
List<T> values = (List<T>) this.value;
values.forEach(clazz::cast);
return values;
}
Given some legacy code that returns an untyped List
List list = database.GetCustomers(); //legacy code returns untyped list
we will use a helper function:
public static <T> #NotNull List<T> castList(final #NotNull Iterable sourceList)
{
List<T> result = new ArrayList<>();
for (Object o : sourceList)
result.add((T)o);
return result;
}
to convert the returned list to a generic typed List<T>:
List<Customer> = castList(database.GetCustomers()); //cast the list the appropriate type
Why Java doesn't have extension methods is quite beyond me.
I'm pretty sure you can completely delete the <stuff> , which will generate a warning and you can use an, # suppress warnings. If you really want it to be generic, but to use any of its elements you will have to do type casting. For instance, I made a simple bubble sort function and it uses a generic type when sorting the list, which is actually an array of Comparable in this case. If you wish to use an item, do something like: System.out.println((Double)arrayOfDoubles[0] + (Double)arrayOfDoubles[1]); because I stuffed Double(s) into Comparable(s) which is polymorphism since all Double(s) inherit from Comparable to allow easy sorting through Collections.sort()
//INDENT TO DISPLAY CODE ON STACK-OVERFLOW
#SuppressWarnings("unchecked")
public static void simpleBubbleSort_ascending(#SuppressWarnings("rawtypes") Comparable[] arrayOfDoubles)
{
//VARS
//looping
int end = arrayOfDoubles.length - 1;//the last index in our loops
int iterationsMax = arrayOfDoubles.length - 1;
//swapping
#SuppressWarnings("rawtypes")
Comparable tempSwap = 0.0;//a temporary double used in the swap process
int elementP1 = 1;//element + 1, an index for comparing and swapping
//CODE
//do up to 'iterationsMax' many iterations
for (int iteration = 0; iteration < iterationsMax; iteration++)
{
//go through each element and compare it to the next element
for (int element = 0; element < end; element++)
{
elementP1 = element + 1;
//if the elements need to be swapped, swap them
if (arrayOfDoubles[element].compareTo(arrayOfDoubles[elementP1])==1)
{
//swap
tempSwap = arrayOfDoubles[element];
arrayOfDoubles[element] = arrayOfDoubles[elementP1];
arrayOfDoubles[elementP1] = tempSwap;
}
}
}
}//END public static void simpleBubbleSort_ascending(double[] arrayOfDoubles)

How to get a reversed list view on a list in Java?

I want to have a reversed list view on a list (in a similar way than List#sublist provides a sublist view on a list). Is there some function which provides this functionality?
I don't want to make any sort of copy of the list nor modify the list.
It would be enough if I could get at least a reverse iterator on a list in this case though.
Also, I know how to implement this myself. I'm just asking if Java already provides something like this.
Demo implementation:
static <T> Iterable<T> iterableReverseList(final List<T> l) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return new Iterator<T>() {
ListIterator<T> listIter = l.listIterator(l.size());
public boolean hasNext() { return listIter.hasPrevious(); }
public T next() { return listIter.previous(); }
public void remove() { listIter.remove(); }
};
}
};
}
I just have found out that some List implementations have descendingIterator() which is what I need. Though there is no general such implementation for List. Which is kind of strange because the implementation I have seen in LinkedList is general enough to work with any List.
Use the .clone() method on your List. It will return a shallow copy, meaning that it will contain pointers to the same objects, so you won't have to copy the list. Then just use Collections.
Ergo,
Collections.reverse(list.clone());
If you are using a List and don't have access to clone() you can use subList():
List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);
Guava provides this: Lists.reverse(List)
List<String> letters = ImmutableList.of("a", "b", "c");
List<String> reverseView = Lists.reverse(letters);
System.out.println(reverseView); // [c, b, a]
Unlike Collections.reverse, this is purely a view... it doesn't alter the ordering of elements in the original list. Additionally, with an original list that is modifiable, changes to both the original list and the view are reflected in the other.
If i have understood correct then it is one line of code .It worked for me .
Collections.reverse(yourList);
Its not exactly elegant, but if you use List.listIterator(int index) you can get a bi-directional ListIterator to the end of the list:
//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());
while (li.hasPrevious()) {
String curr = li.previous();
}
I use this:
public class ReversedView<E> extends AbstractList<E>{
public static <E> List<E> of(List<E> list) {
return new ReversedView<>(list);
}
private final List<E> backingList;
private ReversedView(List<E> backingList){
this.backingList = backingList;
}
#Override
public E get(int i) {
return backingList.get(backingList.size()-i-1);
}
#Override
public int size() {
return backingList.size();
}
}
like this:
ReversedView.of(backingList) // is a fully-fledged generic (but read-only) list
java.util.Deque has descendingIterator() - if your List is a Deque, you can use that.
Collections.reverse(nums) ... It actually reverse the order of the elements.
Below code should be much appreciated -
List<Integer> nums = new ArrayList<Integer>();
nums.add(61);
nums.add(42);
nums.add(83);
nums.add(94);
nums.add(15);
//Tosort the collections uncomment the below line
//Collections.sort(nums);
Collections.reverse(nums);
System.out.println(nums);
Output: 15,94,83,42,61
I know this is an old post but today I was looking for something like this. In the end I wrote the code myself:
private List reverseList(List myList) {
List invertedList = new ArrayList();
for (int i = myList.size() - 1; i >= 0; i--) {
invertedList.add(myList.get(i));
}
return invertedList;
}
Not recommended for long Lists, this is not optimized at all. It's kind of an easy solution for controlled scenarios (the Lists I handle have no more than 100 elements).
Hope it helps somebody.
You can also invert the position when you request an object:
Object obj = list.get(list.size() - 1 - position);
For small sized list we can create LinkedList and then can make use of descending iterator as:
List<String> stringList = new ArrayList<>(Arrays.asList("One", "Two", "Three"));
stringList.stream().collect(Collectors.toCollection(LinkedList::new))
.descendingIterator().
forEachRemaining(System.out::println); // Three, Two, One
System.out.println(stringList); // One, Two, Three
You can also do this:
static ArrayList<String> reverseReturn(ArrayList<String> alist)
{
if(alist==null || alist.isEmpty())
{
return null;
}
ArrayList<String> rlist = new ArrayList<>(alist);
Collections.reverse(rlist);
return rlist;
}

Categories