is there any way I can declare constructor to take HashSet as one of arguments and then pass HashSet value directly as argument during object initialization?
I mean something like this:
public class Order {
private Set<Product> products = new HashSet<Product>();
public Order (???) {
this.products = ???
}
}
and then, while initializing object:
Order order = new Order("product1", "product2", "product3");
is it possible?
You can use varargs :
public class Order {
private Set<Product> products;
public Order (Product... products) {
this.products = new HashSet<Product> (Arrays.asList(products));
}
}
But then you pass to the constructor Product instances :
Order order = new Order(new Product("product1"), new Product("product2"), new Product("product3"));
I would recommend something like:
public class Order {
private final Set<String> strings;
public Order(final Set<String> strings) {
this.strings = strings;
}
public Order(final String... strings) {
this(toSet(strings));
}
private static Set<String> toSet(String[] strings) {
final Set<String> ss = new HashSet<>();
for (final String s : strings) {
if (!ss.add(s)) {
throw new IllegalArgumentException("Duplicate string " + s);
}
}
return ss;
}
}
This takes a varargs argument, which allows you to invoke the constructor as you would like.
It also checks for duplicates during initialization, I would suggest that duplicates are an error; but you could just log it and carry on.
The above looks to me like you want a constructor taking varargs of String type, and then create the HashSet via those varargs.
A HashSet can't be created via varargs, so perhaps create the set and then add each element in turn. Or create a collection of those vararg elements, and then construct the HashSet directly from that.
If you really need to use the HashSet in the constructor, I would do something like this in the constructor:
public Order (HashSet<String> myHashSet)
Then, whenever you want to initialise it, call it this way:
Order order = new Order(new HashSet<String>(Arrays.asList("product1", "product2")));
It's not very time efficient, but it works.
Related
public enum Test implements IsSerializable {
FOOD("FOOD", getFoodItems()),//---Getting Error here
HOTEL("HOTEL", getHotels());//---Getting Error here
private String name;
static final List<String> categories = new LinkedList<String>();
Test(String name) {
this.name = name;
}
public List<String> getCategories() {
return this.categories;
}
private List<String> getFoodItems(){
categories.add("Food item1");
categories.add("Food item2");
return categories;
}
private List<String> getHotels(){
categories.add("Hotel 1");
categories.add("Hotel 2");
return categories;
}
}
I am getting error while creating this Enum. I am new to this type Enum . Can anyone help to make this work?
3 main things:
1. getFoodItems() and getHotels() should be static.
The methods need the existing enum to exist and do not even use anything in the enum.
2. don't declare categories as a static attribute..
You use the same categories object(or references to the same object) because it is static. Remove the static keyword before it in order to make it a member attribute. Each object should have it's own list and this is not possible if it is static.
3. create the List inside the method and give it to the constructor
You call the constructor with 2 parameters: the name and the List but the constructor does only accept the name. Create the categories object inside the methand and return it to the constructor.
3 additional improvements from #Holger (see the comments)
4. Think twice before handing out references to mutable lists.
If you pass a mutable list to a method, that method can change the list which could lead to bugs that may be difficult to find.
5. The name is entirely obsolete as there is no getter for it and its value matches the intrinsic name() anyway.
You may want to add it in any case but enumerations already have a method name() that returns the name of the enum.
6. Don’t use LinkedList when you don’t need its special features (in other words, never use it), but rather, use an ArrayList or even better, List.of(item1, item2), to create an immutable list.
ArrayList is more performant that LinkedList in general because it is based on an array and LinkedList is a linked list(as the name says) that has to create an object for every element containing reference to it's neighbours. That is an advantage if you need to add elements in the middle (or the start) of the list or if you need Queue or Dequeue functionality.
public enum Test implements IsSerializable {
FOOD("FOOD",getFoodItems()),//---Getting Error here.
HOTEL("HOTEL",getHotels());//---Getting Error here
private String name;
private final List<String> categories;
private Test(String name,List<String> categories) {
this.name = name;
this.categories=categories;
}
public List<String> getCategories() {
return this.categories;
}
private static List<String> getFoodItems(){
List<String> categories = new LinkedList<>();
categories.add("Food item1");
categories.add("Food item2");
return categories;
}
private static List<String> getHotels(){
List<String> categories = new ArrayList<>();
categories.add("Hotel 1");
categories.add("Hotel 2");
return categories;
}
}
[Edit]
Please also take note of the answer from boot-and-bottet
Static methods should work, if the constructor is fixed. If the list of items is small, why not declare them inline?
public static enum Test implements IsSerializable {
FOOD("FOOD", "Food item1", "Food item2"),
HOTEL("HOTEL", "Hotel 1", "Hotel 2");
private final String displayName;
private final List<String> categories;
Test(String displayName, String... categories) {
this.displayName = displayName;
this.categories = List.of(categories);
}
public String displayName() {
return displayName;
}
public List<String> getCategories() {
return categories;
}
}
Core issue is that enum initialized in static, and from that context you can't reference non-static items (fields, methods).
Also you don't have place for those lists in your enum - constructor accepts only name param.
You could try to use List.of("Food item1", "Food item2") instead for example and adding new field.
I have the ViewValue class defined as follows:
class ViewValue {
private Long id;
private Integer value;
private String description;
private View view;
private Double defaultFeeRate;
// getters and setters for all properties
}
Somewhere in my code i need to convert a list of ViewValue instances to a list containing values of id fields from corresponding ViewValue.
I do it using foreach loop:
List<Long> toIdsList(List<ViewValue> viewValues) {
List<Long> ids = new ArrayList<Long>();
for (ViewValue viewValue : viewValues) {
ids.add(viewValue.getId());
}
return ids;
}
Is there a better approach to this problem?
We can do it in a single line of code using java 8
List<Long> ids = viewValues.stream().map(ViewValue::getId).collect(Collectors.toList());
For more info : Java 8 - Streams
You could do it in a one-liner using Commons BeanUtils and Collections:
(why write your own code when others have done it for you?)
import org.apache.commons.beanutils.BeanToPropertyValueTransformer;
import org.apache.commons.collections.CollectionUtils;
...
List<Long> ids = (List<Long>) CollectionUtils.collect(viewValues,
new BeanToPropertyValueTransformer("id"));
Use google collections. Example:
Function<ViewValue, Long> transform = new Function<ViewValue, Long>() {
#Override
public Long apply(ViewValue from) {
return from.getId();
}
};
List<ViewValue> list = Lists.newArrayList();
List<Long> idsList = Lists.transform(list, transform);
UPDATE:
On Java 8 you don't need Guava. You can:
import com.example.ViewValue;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
Function<ViewValue, Long> transform = ViewValue::getId;
List<ViewValue> source = new ArrayList<>();
List<Long> result = source.stream().map(transform).collect(Collectors.toList());
Or just:
List<ViewValue> source= new ArrayList<>();
List<Long> result = source.stream().map(ViewValue::getId).collect(Collectors.toList());
NEXT UPDATE (The last one after Javaslang to Vavr name change):
Currently it's worth to mention about the solution with Javaslang library(http://www.javaslang.io/) Vavr library (http://www.vavr.io/). Let's assume that we have our list with genuine objects:
List<ViewValue> source = newArrayList(new ViewValue(1), new ViewValue(2), new ViewValue(2));
We could make transformation with List class from Javaslang library (on the long run the collect is not convenient):
List<Long> result = io.vavr.collection.List.ofAll(source).map(ViewValue::getId).toJavaList();
But you will see the power with only the Javaslang lists:
io.vavr.collection.List<ViewValue> source = javaslang.collection.List.of(new ViewValue(1), new ViewValue(2), new ViewValue(3));
io.vavr.collection.List<Long> res = source.map(ViewValue::getId);
I encourage to take a look available collections and new types on that library (I like especially the Try type). You will find the documentation under the following address: http://www.javaslang.io/javaslang-docs/ http://www.vavr.io/vavr-docs/.
PS. Due to the Oracle and the "Java" word within the name they had to change the library name from javaslang to something else. They had decided to Vavr.
EDIT: This answer is based on the idea that you'll need to do similar things for different entities and different properties elsewhere in your code. If you only need to convert the list of ViewValues to a list of Longs by ID, then stick with your original code. If you want a more reusable solution, however, read on...
I would declare an interface for the projection, e.g.
public interface Function<Arg,Result>
{
public Result apply(Arg arg);
}
Then you can write a single generic conversion method:
public <Source, Result> List<Result> convertAll(List<Source> source,
Function<Source, Result> projection)
{
ArrayList<Result> results = new ArrayList<Result>();
for (Source element : source)
{
results.add(projection.apply(element));
}
return results;
}
Then you can define simple projections like this:
private static final Function<ViewValue, Long> ID_PROJECTION =
new Function<ViewValue, Long>()
{
public Long apply(ViewValue x)
{
return x.getId();
}
};
And apply it just like this:
List<Long> ids = convertAll(values, ID_PROJECTION);
(Obviously using K&R bracing and longer lines makes the projection declaration a bit shorter :)
Frankly all of this would be a lot nicer with lambda expressions, but never mind...
I've implemented a small functional library for this usecase. One of the methods has this signature:
<T> List<T> mapToProperty(List<?> objectList, String property, Class<T> returnType)
Which takes the string and uses reflection to create a call to the property then it returns a List backed by the objectList where get and iterator implemented using this property call.
The mapToProperty functions is implemented in terms of a general map function that takes a Function as a mapper though, just as another post described. Very usefull.
I suggest you read up on basic functionl programming and in particular take a look at Functors (objects implementing a map function)
Edit: Reflection really doesn't have to be expensive. The JVM has improved a lot in this area. Just make sure to compile the invocation once and reuse it.
Edit2: Sample code
public class MapExample {
public static interface Function<A,R>
{
public R apply(A b);
}
public static <A,R> Function<A,R> compilePropertyMapper(Class<A> objectType, String property, Class<R> propertyType)
{
try {
final Method m = objectType.getMethod("get" + property.substring(0,1).toUpperCase() + property.substring(1));
if(!propertyType.isAssignableFrom(m.getReturnType()))
throw new IllegalArgumentException(
"Property "+property+" on class "+objectType.getSimpleName()+" is not a "+propertyType.getSimpleName()
);
return new Function<A,R>()
{
#SuppressWarnings("unchecked")
public R apply(A b)
{
try {
return (R)m.invoke(b);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
};
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static <T1,T2> List<T2> map(final List<T1> list, final Function<T1,T2> mapper)
{
return new AbstractList<T2>()
{
#Override
public T2 get(int index) {
return mapper.apply(list.get(index));
}
#Override
public int size() {
return list.size();
}
};
}
#SuppressWarnings("unchecked")
public static <T1,T2> List<T2> mapToProperty(List<T1> list, String property, Class<T2> propertyType)
{
if(list == null)
return null;
else if(list.isEmpty())
return Collections.emptyList();
return map(list,compilePropertyMapper((Class<T1>)list.get(0).getClass(), property, propertyType));
}
}
You could use a wrapper:
public class IdList impements List<Long>
{
private List<ViewValue> underlying;
pubic IdList(List<ViewValue> underying)
{
this.underlying = underying;
}
public Long get(int index)
{
return underlying.get(index).getId()
}
// other List methods
}
Though that's even more tedious work, it could improve performance.
You could also implement your and my solution generic-ly using reflection, but that would be very bad for performance.
There's no short and easy generic solution in Java, I'm afraid. In Groovy, you would simply use collect(), but I believe that involves reflection as well.
That depends on what you then do with the List<Long>, and the List<ViewValue>
For example you might get sufficient functionality from creating your own List implementation that wraps a List<ViewValue>, implementing iterator() with an iterator implementation that iterates over the ViewValues, returning the id.
You can populate a map from the properties of a list of objects (say id as key and some property as value) as below
Map<String, Integer> mapCount = list.stream().collect(Collectors.toMap(Object::get_id, Object::proprty));
I'm writing a program now in Java which is kind of like a server. I got a MemberController, in MemberController it gets Members from the database OR from the cache (to speed up process). This is an example of how it looks:
public class MemberController {
private final TMap<Integer, Member> members;
public MemberController() {
this.members = new THashMap<>();
}
public Member getMemberByID(int id) {
if (members.containsKey(id)) {
return members.get(id);
}
// GET DATA FROM DB
members.put(ID, MEMBER);
return MEMBER;
}
Now, Member contains a BadgeController object, which contains a TMap for the badges. Example of Member:
public class Member {
// FIELDS OF MEMBER HERE
private BadgeController badgeController;
public Member(ResultSet set) {
// SET FIELDS
}
public void InitOtherData() {
badgeController = new BadgeController(id);
}
public BadgeController getBadgeController() {
return badgeController;
}
And BadgeController:
public class BadgeController {
private final int memberId;
private final TMap<String, Badge> badges;
public BadgeController(int memberId) {
this.memberId = memberId;
this.badges = new THashMap<>();
// LOAD FROM DB
}
public Badge getBadge(String code) {
return badges.get(code);
}
Now, I was wondering a few things (all actually refer to the same I guess):
If I get a Member from members, like members.get(1), and I edit the object, like this:
Member member = members.get(1);
member.setId(1);
Will this edit the id inside the TMap as well? So if I do members.get(1) again, it has the updated value?
If I have the member from above, and I change a value of the Badge, for example I do:
Member member = members.get(1);
member.getBadgeController().getBadge('500Members').setActive(true);
Will this result in true being printed?
System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());
I hope my explaination is good enough. It's hard for me to explain it. I'm sorry.
Member member = members.get(1); does not copy the object but just makes a shortcut (reference). Changing member affects the item in your set as well.
To create an effective copy you have to make your object inherit from the Cloneable interface and call the clone() method on it to get a copy.
you need to DEEP copy object by:
implementing clone interface
create a copy constructor (simplest solution as clone)
examples:
// simple copy constructor
public SomerController(SomeController original) {
members = orginal.clone();
}
// more advanced copy constructor
public SomeController(SomeController original) {
Set<Map.Entry<String, String>> entries = orginal.members.entrySet();
members = new HashMap<String,Class>();
Iterator<Map.Entry<String, Class>> iterator = entries.iterator();
while(iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
String key = next.getKey();
// if class contains a collections ( maps, arrays )
// you need to provide a copy here
// ensure to copy whole tree of references
Class value next.getValue();
map.put(key,value);
}
}
Is it possible to pass an argument to a lambdaj Predicate?
public static Matcher<SomeObject> isSpecialObject = new Predicate<SomeObject>() {
public boolean apply(SomeObject specialObj) {
return LIST_OF_SPECIAL_IDS.contains(specialObj.getTypeId());
}
};
I would like to alter the above predicate so I can pass in a list, rather than use the static list LIST_OF_SPECIAL_IDS. Is that possible?
Thanks.
I suspect you want something like:
public static Matcher<SomeObject> createPredicate(final List<String> ids) {
return new Predicate<SomeObject>() {
public boolean apply(SomeObject specialObj) {
return ids.contains(specialObj.getTypeId());
}
};
}
You've got to make it a method rather than just a field, as otherwise you've got nowhere to pass the list. The parameter has to be final so that you can use it within the anonymous inner class.
Let's say I have this:
public class Whatever {
private ArrayList<String> myList = new ArrayList<String>();
// more code goes here
}
or let's say I have this:
public class Whatever {
private ArrayList<String> myList = null;
public Whatever() {
myList = new ArrayList<String>();
}
}
What's the difference between these two initialisations of myList? Would it be wrong to preffer the first variant?
The first variant will always instantiate the array list, the second one only when calling the default constructor. Meaning for the second solution you will have to call the default constructor for any additional constructor you add e.g.
public class Whatever {
private final List<String> myList;
public Whatever() {
myList = new ArrayList<String>();
}
public Whatever(String name) {
this();
// Other stuff done
}
public Whatever(List<String> myList) {
this.myList = myList;
}
}
The (second) "lazy" initialization method might be better if you don't always use the list (e.g. if you set the list in another constructor directly like in my example) and want to avoid creating unnecessary objects. (EDIT: I changed the ArrayList to an interface and set it final. It wasn't part of the question but it is - as mentioned in the comments - the best way to use List collections).
The JVM first executes code such as this (outside the constructor):
public class Whatever {
private ArrayList<String> myList = new ArrayList<String>();
// more code goes here
}
And only then code such as this (inside the constructor):
public class Whatever {
private ArrayList<String> myList = null;
public Whatever() {
myList = new ArrayList<String>();
}
}
So unless the order of execution is somehow important to you i guess #Daff's answer is the right one.
In this particular example, there is no difference except that the first form is shorter.
However, if the attribute initialization expression (potentially) throws exceptions, the second form allows you to catch the exceptions, or declare them as thrown in the constructor signature.
And of course, if you have multiple constructors, the second form allows you to initialize the attribute differently in each constructor ... or use constructor chaining to initialize the attribute the same ... or mix the two styles of initialization.