Selecting specific object(s) from list with Java - java

Probably some basic stuff I am missing here, but what is the best way to select objects matching some criteria from list?
Say we have:
class MyObject {
int id;
String type;
// getters..setters
}
I use it:
List<MyObject> myObjects = new ArrayList<MyObject>();
myObjects = getListOfObjects();
Now lets say that in the myObjects there are 10 items and 3 of them have type=="bla". At the moment I am just looping thru all the objects and within the loop decide if I want it or not, but is there a better way?
I remember that in C# I used to have something like
myObjects.Where(x => x.type.equals("bla"));
PS, I am targeting Java 7 so no lambda for me yet.

I don't think you can do this without creating an index of some kind. So e.g. having Map<String, Map<String, Set<MyObject>>> you could then call index.get("type").get("bla"). But you would have to first construct this structure. This would be useful if a) there are no changes to the properties AND b) you have a LOT of objects. For 10 objects the performance is of no concern here and I would simply just do what you're doing right now and hide it inside some nice handy method.

You could use the LambdaJ library and its Lambda.exists method with some custom Hamcrest matcher. Then you could make your main code look like this:
if (exists(myObjects, typeIs("bla"))) { /* ... */ }
...provided that you create that custom matcher method typeIs by yourself. But I wouldn't go down this way if I had just one place with just 10 items in a list.
It also depends on your data: if your list is sorted, you could do a binary search on it. That's more useful if you have thousands of items in the list, though.
Finally, you could just use Collection.contains: myObjects.contains(blaElement), but that requires that the blaElement has such an equals method that returns "true" when the type matches.

Related

Does HashSet Provide Any Added Value to Performance in This Instance?

So, I'm working with an existing method in Java that returns a List (ArrayList). However, I want to add some functionality to it so that if specified, it will exclude a certain Object. Now I understand that in general using contains() on a HashSet yields better performance vs an ArrayList, but I'm wondering if there is a justifiable performance boost to be had in the two variations of the code I have below:
Notes: listOfAccounts is an ArrayList returned from a DAO call. personalAccount is an Object of type Account.
if (excludePersonalAccount) {
Set<Account> accounts = new HashSet<Account>(listOfAccounts);
if (accounts.contains(personalAccount) {
listOfAccounts.remove(personalAccount);
}
}
VS
if (excludePersonalAccount) {
listOfAccounts.remove(personalAccount)
}
Set<Account> accounts = new HashSet<Account>(listOfAccounts);
The above line takes all of the elements of the ArrayList and adds it to the HashSet. Instead of doing all of that, you could iterate over the List and look to see if your element is contained inside it. If it is, then you can remove it (which is essentially what you second snippet is doing).
For that reason, the second snippet is preferred, as they both run in linear time.

Implementing a Set in Java using a LinkedList

I have to create a class named Myset which includes methods like IsEmpty(), Insert(Object O) etc. I thought to use a Linked list of objects to implement the Myset class. But as I am new to Java, I am stuck with creating the object itself i.e. I am not clear even how to start with. I thought of something like this:
public class Myset {
LinkedList<Object> LL = new LinkedList<Object>();
}
I further have to write a method: public Myset Union(Myset a): Returns a set which is the union of the current set with the set a. This can be done by iterating through a, if the element at a particular index in a is not contained in LL then we add that element to LL. But how do I write this in a Java code? PS: This is an assignment question and we aren't allowed to use Sets implementation.
Some starting points.
You should either use "true" generics:
class MySet<T> {
private final LinkedList<T> objects = new LinkedList<T>();
or leave generics completely out, like:
class MySet {
private final LinkedList objects = new LinkedList();
You see, your solution
LinkedList<Object> LL = new LinkedList<Object>();
will allow that the user can store any kind of object in your set. So, first a String, then an Integer, and so on. Most likely, that is not what you had in mind. In general, collections in Java are about a specific sort of objects, like only Strings, or only Integer objects.
( side note: LL is a bad name for a field - so study java naming guide lines for that, too )
But there is even less sense in use <Object>. That is like using generics without using them at the same point.
And now, that you have a MySet class, you start one by one:
You add a constructor that allows instantiating an object of your class
You add methods (one by one!) that allow reasonable interaction with your class
Thing is: start slowly. Dont try to solve the big things upfront. Instead: just make sure that your class works as Set; so you can add things, you can check that they are in; and so on.
And only when all of these basic things work you should go forward and add stuff like "union".
A linked list doesn't give you any benefit for a general set. You could simply use an object array, ArrayList, Vector etc. instead, as you would have to compare each element to another specific element anyway. If you insert an element, you have to make sure, there isn't already one in it (this is part of the mathematical definition of a set), just as you have to make this sure in unions, intersections and set differences. This means you have to implement comparability, so you should use the Comparable interface instead of Object, too.

Interface with concrete classes [duplicate]

This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
If we consider two implementations below, what's the actual use of the first one?
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
From what I have read in the posts, the first implementation helps in avoiding breaking change like we can change the implementation again as
a=new TreeList<String>();
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
Different implementations of interface List have different performance characteristics for different operations. Which implementation of List you should choose is not arbitrary - different implementations are more efficient for different purposes.
For example, inserting an element somewhere in the middle is expensive on an ArrayList, but cheap on a LinkedList, because of the way the implementations work. Likewise, accessing an element by index is cheap on an ArrayList, but expensive on a LinkedList.
It may happen that when you started writing your program, you used an ArrayList without thinking about it too much, but later you discover that a LinkedList would be more efficient.
When you've programmed against the interface List instead of a specific implementation, it's very easy to change from ArrayList to LinkedList - to the rest of the program, it still looks like a List, so you'd only have to change one line.
Lets say that you have decided to develop a more efficient List implementation of your own. Perhaps one that has better memory management internally, or may be a faster set method (insertion) implementation. You can just implement the List interface and rest of your code will continue to work without any change, except this one line. You can also extend ArrayList and write your own code.
//Old code
List<String> a = new ArrayList<String>();
a.set(0, "Test");
//New code
List<String> a = new MyCustomisedList<String>();
//Same code, but your optimized set logic. May be faster...
a.set(0, "Test");
A TreeList doesn't exist, so lets use a PersistentList as an example.
Lets say you have an #Entity that you want to save to a database:
public class MyMagicEntity {
#OneToMany
List<MyChildEntity> children;
public void setChildren(final List<MyChildEntity> children) {
this.children = children;
}
}
Now, when you create MyMagicEntity then you would do something like
final MyMagicEntity mme = new MyMagicEntity();
final List<MyChildEntity> children = new ArrayList<>();
children.add(new MyChildEntity("one"));
children.add(new MyChildEntity("two"));
children.add(new MyChildEntity("three"));
mme.setChildren(children);
//save to DB
So you created an ArrayList that you passed into your MyMagicEntity, which assigns it to the List - it doesn't care that the underlying implementation is as long as it's a List.
Now, later you do:
final MyMagicEntity mme = //load from DB
final List<Children> children = mme.getChildren();
So, what is children? Well, if we are using JPA and Hibernate it is actually a PersistentList, not an ArrayList.
As we access the members of children, Hibernate will go and pull them from the database. This List is still a List - your program doesn't have to know any of this.
Could you do this without using the List interface? No! Because:
you cannot create a PersistentList
Hibernate cannot create an ArrayList
Whilst this is an extreme example, where the underlying behaviour of the List is completely different, this applies in all sorts of other situations.
For example:
ArrayList and LinkedList have different performance characteristics, you may want to switch
Guava has an ImmutableList which you may want to use
Collections.unmodifyableList also implements List, which you may want to use
You could conceivably have a List backed by a file
The basic idea is that List defines what any list must be able to do, but not how it is done.
Here List is an Interface which contains all common operation method can perform with an List.
List Interface is parent for ArrayList , LinkedList and many more class. So, It can hold all these type of Object reference.
All these List method have different (or own type) Implementation with different class. So, whatever method you use will automatically apply according to override method definition of Object belong to the class.
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
Now , In Your case you can declare both ways is alright. but suppose a Scenario like this.
You are calling some services and you know that return any List Type (not specific) of Object. It may be a LinkedList or ArrayList or any other type of List.
at that time whatever response you get You can easily hold those responses in a List Type of Reference Variable.
and after gathering the result you can differentiate further of Object Type.

Should I implement List interface or extend ArrayList class

I am developing an application where as a background I need to monitor the user activity on particular objects and later when they are visualized they need to be sorted based on the order of which the user used them ( the last used object must be visualized on the first row of a grid for example.)
So if I have an ArrayList where I store the objects which the user is dealing with in order to add the last used object I need to check if it is already in the list and then move it at the first position. If the object is not there I simply add it at the first position of the list.
So instead of doing all these steps I want to make my own list where the logic explained above will be available.
My question is which scenario is better:
Implement the list interface
Extend the ArrayList class and override the ADD method
Create a class that contains an ArrayList and handles any additional functionality.
I.e. prefer composition over inheritance (and in this case, implementing an interface). It's also possible to have that class implement List for relevant cases and just direct the (relevant) operations to the ArrayList inside.
Also note that LinkedHashMap supports insertion order (default) and access order for iteration, if you don't need a List (or if you can suitably replace it with a Map).
So instead of doing all these steps i want to make my own list where
the logic explained above will be available.
I would try to refactor your design parameters (if you can) in order to be able to use the existing Java Collection Framework classes (perhaps a linked collection type). As a part of the Collections Framework, these have been optimized and maintained for years (so efficiency is likely already nearly optimal), and you won't have to worry about maintaining it yourself.
Of the two options you give, it is possible that neither is the easiest or best.
It doesn't sound like you'll be able to extend AbstractList (as a way of implementing List) so you'll have a lot of wheel reinvention to do.
The ArrayList class is not final, but not expressly designed and documented for inheritance. This can result in some code fragility as inheritance breaks encapsulation (discussed in Effective Java, 2nd Ed. by J. Bloch). This solution may not be the best way to go.
Of the options, if you can't refactor your design to allow use of the Collection classes directly, then write a class that encapsulates a List (or other Collection) as an instance field and add instrumentation to it. Favor composition over inheritance. In this way, your solution will be more robust and easier to maintain than a solution based on inheritance.
I think LinkedHashMap already does what you need - it keeps the elements in the order they were inserted or last accessed (this is determined by the parameter accessOrder in one of the constructors).
https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html
EDIT
I don't have enough reputation to comment, so I'm putting it here: You don't actually need a map, so Venkatesh's LinkedHashSet suggestion is better.
You can do something like this:
<T> void update(Set<T> set, T value) {
set.remove(value);
set.add(value);
}
and then
LinkedHashSet<String> set = new LinkedHashSet<>();
update(set, "a");
update(set, "b");
update(set, "c");
update(set, "a");
Iterator<String> it = new LinkedList<String>(set).descendingIterator();
while (it.hasNext()) {
System.out.println(it.next());
}
Output:
a
c
b
You might try using HashMap<Integer, TrackedObject> where TrackedObject is the class of the Object you're keep track of.
When your user uses an object, do
void trackObject(TrackedObject object)
{
int x = hashMap.size();
hashMap.add(Integer.valueOf(x), object);
}
then when you want to read out the tracked objects in order of use:
TrackedObject[] getOrderedArray()
{
TrackedObject[] array = new TrackedObject[hashMap.size()];
for(int i = 0; i < hashMap.size(); i++)
{
array[i] = hashMap.get(Integer.valueOf(i));
}
return array;
}
A LinkedHashSet Also can be helpful in your case. You can keep on adding elements to it, it will keep them in insertion order and also will maintain only unique values.

What is the use of singletonList?

I was looking around for some elegant solution to removing null values from a List. I came across the following post, which says I can use list.removeAll(Collections.singletonList(null));
This, however, throws an UnsupportedOperationException, which I'm assuming is because removeAll() is attempting to do some mutative operation on the immutable singleton collection. Is this correct?
If this is the case, what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?
Thanks in advance.
It works like a charm:
List<String> list = new ArrayList<String>();
list.add("abc");
list.add(null);
list.add("def");
list.removeAll(Collections.singletonList(null));
System.out.println(list); //[abc, def]
Indeed Collections.singletonList(null) is immutable (which is unfortunately hidden in Java[1]), but the exception is thrown from your list variable. Apparently it is immutable as well, like in example below:
List<String> list = Arrays.asList("abc", null, "def");
list.removeAll(Collections.singletonList(null));
This code will throw an UnsupportedOperationException. So as you can see singletonList() is useful in this case. Use it when client code expects a read-only list (it won't modify it) but you only want to pass one element in it. singletonList() is (thread-)safe (due to immutability), fast and compact.
[1] E.g. in scala there is a separete hierarchy for mutable and immutable collections and API can choose whether it accept this or the other (or both, as they have common base interfaces)
To answer your actual question :
what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?
The typical use is if you have one element and want to pass it to a method that accepts a List, ie
public void registerUsers(List<User> users) {...}
User currentUser = Login Manager.getCurrentUser();
registerUsers(Collections.singletonList(currentUser));
The removeAll() is a special case for this.
Has your list been protected with
Collections.unmodifiableList(list)
Because if you have protected it and try to modify it later you get that error.

Categories

Resources