I'm coding an Android app with Firebase and want to write an object to the database:
public class newEvent {
public String whoEv;
public String whereEv;
public String whenEv;
public String whatEv;
public newEvent() {}
public newEvent(String whoEv, String whereEv, String whenEv, String whatEv) {
this.whoEv = whoEv;
this.whereEv = whereEv;
this.whenEv = whenEv;
this.whatEv = whatEv;
}
}
This works, but as you can see they are all 'just' strings. What i want is to have the first argument to be a List, Firebase doesnt allow String[] uploads/writings.
The reason is to be able to pass more names into the whoEv as separated Strings/Objects. (to give each name a boolean if they are coming or not).
Now to the exact problem:
public newEvent(List<String> whoEv, String whereEv, String whenEv, String whatEv) {
this.whoEv = whoEv;
this.whereEv = whereEv;
this.whenEv = whenEv;
this.whatEv = whatEv;
}
When i use this, i have no clue how to write the proper code:
newEvent test = new newEvent(List<String>("derp","max"), "Amsterdam", "31/12/2016", "NewYears Eve");
The above obviously doesnt work. Expression expected or unexpected token. What am i missing or doing wrong? Already thanks for reading this!
Edit: Total idiot idea to use List<String>if i want to pass boolean values with the strings... Dont got clue what to use instead though.
Fixed it:
newEvent test = new newEvent("Meppel", "31/12/2016", "Oudjaarsdag", new String[]{"derp", "Sir", "max"});
And in the class as:
`public class newEvent {
public ArrayList<String> wie;
public String waar;
public String wanneer;
public String wat;
public newEvent() {}
public newEvent(String waar, String wanneer, String wat, String... wie) {
this.wie = new ArrayList<>(Arrays.asList(wie));
this.waar = waar;
this.wanneer = wanneer;
this.wat = wat;
}
List is an Interface, you can't directly use it with out a implementation class. You can use one of default jdk provided classes which implements List interface. example ArrayList, LinkedList.
Go through this link on List Implementations and you will understand how you can pass a list of string as argument.
Is it Java? May be you need add the word "new" before List...
And don't forget List is an interface type, so here need use some inheritance class. ArrayList for example
Related
I'm new to Java and I am trying to write a description class that will return an array of strings from calling describe through my interface.
this line: return Collections.toString(items); is throwing the error in the title, and I can't understand why.
I know that I need to return type string and that items are not currently a string but I'm new to Java and not sure what to change.
trace error when run: java.lang.Error: Unresolved compilation problem:
The return type is incompatible with Describe.describe()
package uk.ac.uos.assignment;
import java.util.*;
public class Description implements Describe {
private Collection<Describe> items;
public Description() {
this.items = new ArrayList<>();
}
public String describe() {
return Collections.toString(items);
}
public void add(Describe d) {
items.add(d);
}
}
and this is my interface:
package uk.ac.uos.assignment;
interface Describe {
String describe();
}
Now, in the "describe()" method, I would suggest you do the following:
1) Create an empty String;
2) Iterate through the Collection and add every element, as a string, to the empty string you have created;
3) Return the String.
The basic algorithm I described above, now here's somewhat of an implementation:
public String describe(){
StringBuilder y = new StringBuilder();
items.forEach(i -> y.append(i.toString()));
return y.toString();
}
Note: For this to work, your project must be set to use Java 8 or newer. If it is not, you will need to do a classical iteration through the Collection and then append each element to the StringBuilder.
Note 2: Your "Description" class must have its "toString()" method implemented. Before implementing it though, you should use an #Override annotation, just above the method:
#Override
public String toString(){...}
What I understand is that you want a String array returning the String representation of each of those items in your Collection<Describe> items.
Iterate over the collection and call the toString() method of every Describe item provided that the Describe class has its own implementation of toString.
This would get you a String for each of those items in your collection, collect them and return at the end.
public String describe() {
List<String> descriptions = new ArrayList<String>(items.size());
for(Describe item: items) {
descriptions.add(item.toString());
}
return descriptions.toArray(new String[items.size()]);
}
Me and one of my colleague were trying to solve the following problem:
Lets take an example of class A
One of my colleagues was facing problem of extracting one particular property from A.
Fetching one property from One particular class (in this case A) is easy. but lets
assume that you have multiple classes (A1, A2...) and you want to fetch one
particular property from the collection of these classes with more and more reusability of code.
for example
public class A {
private String name;
.
.
.
}
List<String> listOfNames = createNameList(listOfAInstances);
createNameList() method would be like following:
List<String> tempList = new ArrayList<>();
for(A a : listOfAInstances) {
tempList.add(a.getName());
}
return tempList;
now if there are multiple classes I have to do this for each class and different properties.
I suggested two approaches:
Reflection based approach.
Create an interface called "PropertyExtractable" and put a method in it called "extractProperty" in it.
As shown below:
interface PropertyExtractable {
Object extractProperty();
}
public class A implements PropertyExtractable {
private String name;
.
.
.
public Object extractProperty() {
return this.name;
}
}
For this I can write some utility method which then can be used everywhere i.e.
public Object getPropertiesOfPropertyExtractable(PropertyExtractable prExtractable) {
return prExtractable.extractProperty();
}
This was the background, one other colleague of mine had different opinion about 2nd approach, he told me it seems like anti-pattern. He tried to explain to me but I didn't get it entirely so and hence I am asking here.
I am trying to compare this example with the Comparator interface in Java. Like java allows us to use Comparator on any of the custom object class and allows us to define the logic for comparison then why can't I define the logic for extraction
Further more interfaces can be used in this way, then why shouldn't we use it
I want to know is this approach an anti-pattern? why?
You can place extracting code in separate method and reuse it:
class A {
private String name;
public String getName() {
return name;
}
}
class B {
private String surname;
public String getSurname() {
return surname;
}
}
public class SomeClass {
private <T> List<String> extractFields(List<T> list, Function<T, String> extractorFunction) {
return list.stream().map(extractorFunction).collect(Collectors.toList());
}
public void someMethod() {
List<A> listOfInstancesA = new ArrayList<>();
List<B> listOfInstancesB = new ArrayList<>();
// fill lists
List<String> fieldsA = extractFields(listOfInstancesA, A::getName);
List<String> fieldsB = extractFields(listOfInstancesB, B::getSurname);
}
}
The situation you describe is working with a legacy system which you don't want to change.
Since if you weren't you'd introduce an interface for the common properties (like your example for the Comparator interface). You introduced an interface without a meaning which may be an anti-pattern since you actually need a functional interface: PropertyExtractable vs. NamedObject=> has a method: String getName()).
If you want to implement Reflection, then your interface may be correct but I don't see it (e.g. in your case you already have Reflection built in into Java).
Usually you use the Adapter pattern to get a property/method from an object which doesn't implement the requested interface.
I'm using a method that takes a Class<T> as a parameter.
The class I want to pass as a parameter also uses T. It is declared as public class MyObject<T> and has a member declared as public T mMyVar; I then have 2 classes I sometimes use for mMyVar called MyVarObject1 and MyVarObject2.
Example:
private class MyObject<T> {
public T mMyVar;
}
private class MyVarObject1 {
// some variables
}
private class MyVarObject2 {
// some variables
}
Specifically, the method I'm invoking is the JacksonUtil method fromJsonArray.
I'm not sure of the proper syntax here. JacksonUtil needs to know the exact model structure so it can parse the json, but I'm having trouble figuring out the proper syntax for this line:
MyObject<MyVarObject1> result = JacksonUtil.fromJsonArray(jsonStr, MyObject<MyVarObject1>.class);
What I have there doesn't work. My IDE selects the second parameter and says, "Cannot select from parameterized type."
I had a same problem while using with retrofit, This is my solution -
public class ResponseDS<T> {
public int s;
public String e;
public T d;
}
And if you need array of object then,
public class ResponseDSs<T> {
public int s;
public String e;
public T[] d;
}
And below is how I am using it for Retrofit -
Call<ResponseDS<UserDS>> userModelCall = ZivaUtils.getRetrofit().getUser();
I think you have the same problem, hope my solution will help you :)
I do TypedToken from Gson to parse custom objects, I think you can find something similar to use with Jackson, i will edit my answer if i find something later.
You may use TypeToken to load the json string into a custom object.
Gson gson = new Gson();
//This is an example, you probably get this from your server as Json String
MyObject<MyObject1> user = new MyObject<MyObject1>();
String myObjectAsString = gson.toJson(user);
//then parse into your custom object
MyObject other = gson.fromJson(myObjectAsString, new TypeToken<MyObject<MyObject1>>(){}.getType());
This class is where I want to call the arrays and set the arrays to empty within the parameters
public class ElectronicsEquipmentSupplier {
private int currentMonth;
private int currentYear;
private String rangeOfProducts;
private CustomerDetailsList details; //Contains the customer details array
private PurchaseOrderList pal; //Contains the purchase array
public ElectronicsEquipmentSupplier(int currentMonth, int currentYear,
String rangeOfProducts ) {
this.currentMonth = currentMonth;
this.currentYear = currentYear;
this.rangeOfProducts = rangeOfProducts;
}
}
This is the class where the array is created. It pulls information from a separate class called PurchaseOrder and then sets the list.
public class PurchaseOrderList {
private ArrayList<PurchaseOrder> purchaseCollection;
public PurchaseOrderList() {
purchaseCollection = new ArrayList<PurchaseOrder>();
}
The CustomerDetailsList class is essentially the same. Just not sure as to the best way to set the array to empty when called in the ElectronicsEquipmentSupplier.
Simply wrap the collection's own clear() method with a publicly-accessible method in your PurchaseOrderClass:
public class PurchaseOrderList {
private ArrayList<PurchaseOrder> purchaseCollection;
public PurchaseOrderList() {
purchaseCollection = new ArrayList<PurchaseOrder>();
}
//THIS IS THE IMPORTANT PART
public void clearPurchaseCollection() {
purchaseCollection.clear();
//You could also accomplish the same thing by reinitializing the list:
//purchaseCollection = new ArrayList<PurchaseOrder>();
}
}
Note however, that calling new PurchaseOrderList() already guarantees an empty purchaseCollection list, since you initialize it in the constructor that way.
So the only time you would need to call clearPurchaseCollection() is if you are reusing this object and want to clean it out first. Depending on the rest of your application, that may be necessary, but it may also just be simpler to throw away that instance and create a new PurchaseOrderList(). Totally depends on the situation.
I'm not quite sure how to do this, but I find myself using a list of lists quite often in this particular project. I think I'd like to refactor this into it's own collection. Basically, it's a list of users and their attributes. The object I'm using is a List<List<String>>. I think I'd like to make a drop-in replacement that maybe extends ArrayList and call it UserList or something similar.
Note: my only real goal is to keep from typing List<List<String>> everywhere.
What would be the best approach to take with this?
EDIT: Thanks. I guess I knew something could be better. Just couldn't quite put my finger on it. I had initially avoided creating a User class because I wasn't sure how I would easily be able to iterate over the attributes.
There is no need to create a custom List<List<String>> for these requirements.
Create a User class to store all the attributes, then create a List<User>.
You shouldn't.
You'll spend a lot more time writing this new class than just typing a few extra characters.
If you really want to make a new class.
Why not like this?
public class User {
private String attribute1;
private String attribute2;
//etc.
public String getAttribute1() {
return attribute1;
}
public void setAttribute1(String value) {
attribute1 = value;
}
public String getAttribute2() {
return attribute2;
}
public void setAttribute2(String value) {
attribute2 = value;
}
//etc.
}
If you insist on using nested Lists.
I suggest creating a wrapper class that would look something like this:
public class Users {
private List<List<String>> twoDList;
public String get(int x, int y) {
return twoDList.get(y).get(x);
}
public void set(int x, int y, String value) {
twoDList.set(y, twoDList.get(y).set(x, value));
}
//etc.
}