Cannot create a generic array in Java - java

I try to create a generic array but I'm taking the error of the title.
ByteConverter<Product> byteconverter = new ByteConverter<Product>();
//into an inner class I have to declare a final field
final ByteConverter<Product>[] byteconverter2 = {byteconverter};
So, I searched at the Stackoverflow for a possible solution. I found something similar here: Cannot create an array of LinkedLists in Java...? , so I canged my code to the following:
final ByteConverter<Product>[] byteconverter2 = {(ByteConverter<Product>[])byteconverter};
but I still take the same error. I can't understand why..Any help please?

final ByteConverter<Product>[] byteconverter2 =
new ByteConverter[]
{
byteconverter
};
this works well

This compiles, though with a warning
ByteConverter<Product> byteconverter = new ByteConverter<Product>();
ByteConverter<Product>[] byteconverter2 = new ByteConverter[] { byteconverter };
Read here http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html about restrictions for generics

Related

Initializing empty instance variables in constructor

I have a LogAnalyzer class that looks at a web server log, creates LogEntry objects and puts those objects into HashMaps for analyzing.
My LogAnalyzer class has these fields:
private int totalVisits;
private int uniqueVisits;
private ArrayList<LogEntry> records;
private HashMap<String, ArrayList<LogEntry>> uniqueIPs; //<address, log entries>
private HashMap<String, ArrayList<LogEntry>> dailyRecords; // <date, log entries>
My constructor looks like this:
public LogAnalyzer() {
records = new ArrayList<>();
dailyRecords = new HashMap<>();
uniqueIPs = new HashMap<>();
}
And then I have this method:
public void initializeRecords(String path){
readFile(path); //reads the web log file and fills out the records and dailyRecords fields
getUniqueIPs(); //fills out the uniqueIPs HashMap field.
uniqueVisits = uniqueIPs.size(); //fills out the uniqueVisits field
totalVisits = records.size(); //fills out the totalVisits field
}
So my question:
I have read (but don't really understand) it's "bad" to call methods inside the constructor. However it seems like the constructor is pointless here, since it is actually the initializeRecords that is doing all of the meaningful work of "creating" the object.
I don't have the background in Java or programming to understand the explanations I've found so far. There is a lot of talk of overriding things, and I think that's what I'm not clear on. I'm wondering why I should keep my constructor and this method seperated, in simple terms that a beginner can understand.
**EDIT: ** Here's the code for readFile():
public void readFile(String filename) {
FileResource fr = new FileResource(filename);
for (String line : fr.lines()){
LogEntry le = WebLogParser.parseEntry(line);
String date = le.getAccessTime().toString().substring(4, 10);
if (dailyRecords.keySet().contains(date)){
dailyRecords.get(date).add(le);
}
else{
ArrayList<LogEntry> entries = new ArrayList<>();
entries.add(le);
dailyRecords.put(date, entries);
}
records.add(le);
}
Keeping the two methods allows you more flexibility in the use of your code. You can instantiate your LogAnalyzer without knowing the path to your log. I would rename initializeRecords to processRecords which IMO is more descriptive of what you are doing there.
We should create the object first and then call methods on it. If your readFile method were to throw an Exception because it can't read the file for example. I would find it very odd to get that exception when I am constructing the object. The point of the constructor is to provide an object that can be used to do something.
It's not a good practice to call methods from within constructor, because Java always calls the most derived method, which means we could call a method on a half-initialized object.
To answer your question,
public LogAnalyzer() {
records = new ArrayList<>();
dailyRecords = new HashMap<>();
uniqueIPs = new HashMap<>();
}
What the above part exactly does is, it gives the variables, records, dailyRecods and uniqueIPs a physical address in the memory stack.
When we write something like private ArrayList<LogEntry> records; in the class, at this time only a reference is generated, but actual initialization happens only when records = new ArrayList<>(); this line gets executed.
Hope this clarifies your doubt!!!
As you can see in readFile() it uses the following instruction
dailyRecords.keySet().contains(date)
without initializing dailyRecords prior to it. So if you do not initialize dailyRecords either while declaring it or in constructor you will face NullPointerException.
In your case instead of using constructor for initialization you can use declaration part like this
private HashMap<String, ArrayList<LogEntry>> dailyRecords = new HashMap<>();

Why can't I cast an object to collection in Java?

I am writing a Unit Test for a class as follows:
#Test
void testCreateStackResources()
{
List<StackResource> stackResourceListExpected = new ArrayList<>();
StackResource stackResource = new StackResource();
stackResource.setLogicalResourceId("Sample-Logical-ID");
stackResourceListExpected.add(stackResource);
ListStackResourcesResult listStackResourcesResult = new ListStackResourcesResult();
StackResourceSummary stackResourceSummary = new StackResourceSummary();
stackResourceSummary.setLogicalResourceId("Sample-Logical-ID");
listStackResourcesResult.setStackResourceSummaries((Collection<StackResourceSummary>) stackResourceSummary); // Problem in this line
Mockito.when(amazonCloudFormation.listStackResources(Mockito.any(ListStackResourcesRequest.class))).thenReturn(listStackResourcesResult);
List<StackResource> stackResourceListResult = cloudFormationManager.createStackResources(Mockito.anyString());
Assert.assertEquals(stackResourceListExpected, stackResourceListResult);
}
Now, when I run this code, it gives me an error that I can't cast StackResourceSummary to a Collection in Java.
java.lang.ClassCastException: com.amazonaws.services.cloudformation.model.StackResourceSummary cannot be cast to java.util.Collection
On the other hand, if I make an array list before, add the object of StackResourceSummary to the list and then run the UT, it gives me the
objc[3648]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java (0x10d19c4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10ea194e0). One of the two will be used. Which one is undefined.
This is very weird behaviour. I don't know why can't I cast this to a collection? Please help. Thanks!
PS: There is a seperate class called ListStackResourcesResult which has a setter as follows:
public void setStackResourceSummaries(java.util.Collection<StackResourceSummary> stackResourceSummaries) {
if (stackResourceSummaries == null) {
this.stackResourceSummaries = null;
return;
}
this.stackResourceSummaries = new com.amazonaws.internal.SdkInternalList<StackResourceSummary>(stackResourceSummaries);
}
And I am trying to use this method above.
That is because StackResourceSummary does not extend or implement anything related to a collection.
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudformation/model/StackResourceSummary.html
What you need to to is create a collection and add your instance of StackResourceSummary to it. For example like so:
List<StackResourceSummary> stackResourceSummaries = new ArrayList<StackResourceSummary>();
stackResourceSummaries.add(stackResourceSummary)
or maybe like so
Arrays.asList(stackResourceSummary)
or use a third party lib like guava collections.
Then you should use that collection as an argument.
listStackResourcesResult.setStackResourceSummaries(stackResourceSummaries); // Problem gone in this line

Java - Remove "Optional" from a variable (convert)

for a piece of homework, I have to set a variable. The set method given to me, converts that into "Optional". However, I have to store this variable in an ArrayList which doesn't allow Optional variables.How can I convert the variable so it is no longer Optional?
The set method:
public void setParentVertex(IVertex<T> parentVertex)
{
if(parentVertex == null)
this.parentVertex = Optional.empty();
else
this.parentVertex = Optional.of(parentVertex);
}
Where I'm trying to use it:
ArrayList<IVertex<T>> path = new ArrayList<IVertex<T>>();
IVertex<T> parent = current.getLabel().getParentVertex();
path.add(parent);
The error I keep receiving is: "Error: incompatible types: Optional> cannot be converted to IVertex" due to the line where I declare the variable "parent".
Thank you.
Here is the correct version
List<IVertex<T>> path = new ArrayList<IVertex<T>>();
current.getLabel().getParentVertex().ifPresent(path::add)
Also it would be good to rewrite setParentVertex function:
public void setParentVertex(IVertex<T> parentVertex) {
this.parentVertex = Optional.ofNullable(parentVertex);
}
I think you don't have to add it to your list, if there is no value. So just do
if(nameOfOptional.isPresent()){
list.add(nameOfOptional.get());
}
First, add a check to find the value is present or not (by calling isPresent()) and then if the value is present then add to your ArrayList path object as shown below:
ArrayList<IVertex<T>> path = new ArrayList<>();
Optional<IVertex<T>> parent = current.getLabel().getParentVertex();
if(parent.isPresent()) {
path.add(parent.get());
}
or the shorter form is shown below which uses ifPresent method:
ArrayList<IVertex<T>> path = new ArrayList<>();
Optional<IVertex<T>> parent = current.getLabel().getParentVertex();
parent.ifPresent(path::add);
Also, I suggest you have a look at the Optional API methods here.
As a side note, I recommend you to use diamond <> operator while declaring generic types (like shown above i.e., new ArrayList<>()) , so that your code will be less verbose.

java.lang.NullPointerException error message

ImgSet[0] = new ImageIcon("bandeira-portugal.png",
"Portugal");
ImgSet[1] = new ImageIcon("south_korea-32.png",
"South_Korea");
ImgSet[2] = new ImageIcon("China-icon.png",
"China");
ImgSet[3] = new ImageIcon("Japan.png",
"Japan");
This is my code for the image icons. I am getting the error message "java.lang.NullPointerException"!
Can you please tell me how to fix it?
My picture files are in the program folder!
Yes I did set the variable ImgSet if that's got anything to do with it.
private Icon[] ImgSet;
Initialize your array first. Thats all:)
private Icon[] ImgSet = new Icon[4];
Remember that you cannot change arrays length, after you initialize it, so select a good size, in this example it is 4.
If your collection is dynamic (you will add more elements, depending on runtime), change it to list, or set. Remember that arrays are fast, but their size is not editable.
You're just declaring ImgSet variable by doing:
private Icon[] ImgSet;
To initialize you should do something like:
private Icon[] ImgSet = new Icon[n];
Where n should be an initialized int or Integer.
You may way to use something like ArrayList or LinkedList instances from the java.util package.
Maybe you forget to initialize your array before.
Try this
ImageIcon[] ImgSet =
{
new ImageIcon("bandeira-portugal.png", "Portugal"),
new ImageIcon("south_korea-32.png", "South_Korea"),
new ImageIcon("China-icon.png", "China"),
new ImageIcon("Japan.png","Japan")
};
Doubts: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

Unable to add a String to an ArrayList: "misplaced construct(s)"

I am trying to add a string to an ArrayList in Java, but I can't seem to get it to work.
Currently, I have the following code:
List food_names = new ArrayList();
food_names.add("pizza");
Why do I get these errors:
Syntax error on token ""pizza"", delete this token
Syntax error on token(s), misplaced construct(s)
You have to use food_names.add("pizza") in function, for example:
public void AddFood()
{
food_names.add("pizza");
}
Hope helps
why don't you use List Generics List interface.
List<String> food_names = new ArrayList<String>();
food_names.add("pizza");
This shouldn't give any error.
I suspect that those statements are at the top level of a class. The first one is OK there, but the second one can only be inside a code block; e.g. a method or constructor body. See #tomasBull's answer for an example of where you can do that.
The compiler is trying to parse food_names.add("pizza"); as a declaration, and is getting thoroughly confused.
There is another solution
food_names.add(new String("pizza"));
Class Example
{
//**Do not place it here.**
List food_names = new ArrayList();
food_names.add("pizza");
public static void main(String[] args)
{
//**You should place it here**
List food_names = new ArrayList();
food_names.add("pizza");
}
}
I'm not sure you're initializing the ArrayList correctly. Try
ArrayList<String> food_names = new ArrayList<String>();
Also double check you've imported ArrayList. Or try removing the quotation marks around pizza.
Disclaimer: I'm probably wrong but I'm laying in bed typing this from my phone, haha. Good luck.

Categories