Type safety / List is a raw type - class

Hi i'm getting this warning and I need help on how to fix it, it appears under my combine method which merges two existing lists together, the warning is
Type safety: The expression of type List needs unchecked conversion to conform to List and List is a raw type. References to generic type List should be paramaterized.
For my equals method, my List class says that it's a raw type as well
public class List<T> implements ListInterface<T> {
private int lastIndex;
private Object[] elements;
public List() {
elements = new Object[10];
lastIndex = 0;
}
public List<T> combine(List<T> list2) {
List<T> l = new List(); // This is where the warning is underlined
try {
for (int i = 1; i <= lastIndex; i++)
l.add (retrieve (i));
for (int i = 1; i <= list2.lastIndex; i++)
l.add (list2.retrieve (i));
}
catch (ListException e) {
System.out.println("Should not occur (Combine)");
}
return l;
}
public boolean equals(Object list) {
if (list == null) {
return false;
}
List myList = (List)list; // cast to type List // Under each List, it says it is a raw type. References to generic type List<T> should be paramaterized.
if (myList.getClass() != this.getClass()) {
return false;
}
if (myList.length() != this.length()) {
return false;
}
try {
for (int pos = 1; pos <= lastIndex; pos++) {
if (!myList.retrieve(pos).equals(this.retrieve(pos))) {
return false;
}
}
}
catch (ListException e) {
System.out.println("Should not occur");
}
return true;
}
}
Thank you!

Related

Avro serialize and desiaralize List<UUID>

I cannot understand how to serialize List to binary format and deserialize back to List. I have tried to use CustomEncoding for this purpose:
public class ListUUIDAsListStringEncoding extends CustomEncoding<List<UUID>> {
{
schema = Schema.createArray(Schema.createUnion(Schema.create(Schema.Type.STRING)));
schema.addProp("CustomEncoding", "com.my.lib.common.schemaregistry.encoding.ListUUIDAsListStringEncoding");
}
#Override
protected void write(Object datum, Encoder out) throws IOException {
var list = (List<UUID>) datum;
out.writeArrayStart();
out.setItemCount(list.size());
for (Object r : list) {
if (r instanceof UUID) {
out.startItem();
out.writeString(r.toString());
}
}
out.writeArrayEnd();
}
#Override
protected List<UUID> read(Object reuse, Decoder in) throws IOException {
var newArray = new ArrayList<UUID>();
for (long i = in.readArrayStart(); i != 0; i = in.arrayNext()) {
for (int j = 0; j < i; j++) {
newArray.add(UUID.fromString(in.readString()));
}
}
return newArray;
}
}
'write' method seems to pass correctly, but 'read' method stoped with exception 'java.lang.ArrayIndexOutOfBoundsException: 36' when trying to read string.
What I do wrong and how to deserialize data correctly?
Solved myself:
Put my encoding class here if someone will need it:
public class ListUuidAsNullableListStringEncoding extends CustomEncoding<List<UUID>> {
{
schema = Schema.createUnion(
Schema.create(Schema.Type.NULL),
Schema.createArray(Schema.create(Schema.Type.STRING))
);
}
#Override
protected void write(Object datum, Encoder out) throws IOException {
if (datum == null) {
out.writeIndex(0);
out.writeNull();
} else {
out.writeIndex(1);
out.writeArrayStart();
out.setItemCount(((List) datum).size());
for (Object item : (List) datum) {
if (item instanceof UUID) {
out.startItem();
out.writeString(item.toString());
}
}
out.writeArrayEnd();
}
}
#Override
protected List<UUID> read(Object reuse, Decoder in) throws IOException {
switch (in.readIndex()) {
case 1:
var newArray = new ArrayList<UUID>();
for (long i = in.readArrayStart(); i != 0; i = in.arrayNext()) {
for (int j = 0; j < i; j++) {
newArray.add(UUID.fromString(in.readString()));
}
}
return newArray;
default:
in.readNull();
return null;
}
}
}

Refresh suggestion list on change - cn1 autocomplete

I've implemented a custom autocomplete text field in a cn1 app, but I've noticed it only loads the suggestions list once, after that any change in the text doesn't trigger a change in the list, and the getSuggestionModel() is never called again. How can I achieve this (in my mind, basic) functionality?
This is my autocomplete class:
public class ForumNamesAutocomplete extends AutoCompleteTextField {
List<String>suggestions = new LinkedList<String>();
List<Map<String,Object>> fData;
StateMachine mac;
int currentIndex;
String prevText;
public static final String KEY_FORUM_NAME = "name";
public static final String KEY_FORUM_ID = "id";
public static final String KEY_FORUM_DESC = "desc";
public ForumNamesAutocomplete(StateMachine sm){
super();
mac = sm;
if(sm.forumData != null){
fData = mac.forumData;
}
}
#Override
protected boolean filter(String text) {
if(text.equals(prevText)){
return false;
}
setSuggestionList(text);
fireDataChanged(DataChangedListener.CHANGED, text.length());
prevText = text;
return true;
}
#Override
public void fireDataChanged(int type, int index) {
super.fireDataChanged(type, index);
}
public void setSuggestionList(String s){
if(suggestions == null){
suggestions = new LinkedList<String>();
}else{
suggestions.clear();
}
LinkedList<String> descList = new LinkedList<String>();
for(int i = 0;i<fData.size();i++){
boolean used = false;
Map<String,Object> forumMap = fData.get(i);
if(((String)forumMap.get(KEY_FORUM_NAME)).indexOf(s) != -1){
suggestions.add((String)forumMap.get(KEY_FORUM_NAME));
used = true;
}
if(!used && ((String)forumMap.get(KEY_FORUM_DESC)).indexOf(s) != -1){
descList.add((String)forumMap.get(KEY_FORUM_NAME));
}
}
suggestions.addAll(descList);
}
#Override
protected ListModel<String> getSuggestionModel() {
return new DefaultListModel<String>(suggestions);
}
}
This used to be simpler and seems to be a bit problematic now as explained in this issues.
Technically what you need to do is return one model and then mutate said model/fire modified events so everything will refresh. This is non-trivial and might not work correctly for all use cases so ideally we should have a simpler API to do this as we move forward.
After additional debugging, I saw that the getSuggestionModel() method was being called only during initialization, and whatever the suggestion list (in suggestion object) was at that point, it remained so. Instead I needed to manipulate the underlying ListModel object:
public class ForumNamesAutocomplete extends AutoCompleteTextField {
ListModel<String>myModel = new ListModel<String>();
...
#Override
protected boolean filter(String text) {
if(text.length() > 1){
return false;
}
setSuggestionList(text);
return true;
}
private void setSuggestionList(String s){
if(myModel == null){
myModel = new ListModel<String>();
}else{
while(myModel.getSize() > 0)
myModel.removeItem(0);
}
for(int i = 0;i<fData.size();i++){
boolean used = false;
Map<String,Object> forumMap = fData.get(i);
if(((String)forumMap.get(KEY_FORUM_NAME)).indexOf(s) != -1){
myModel.addItem((String)forumMap.get(KEY_FORUM_NAME));
used = true;
}
if(!used && ((String)forumMap.get(KEY_FORUM_DESC)).indexOf(s) != -1){
myModel.addItem((String)forumMap.get(KEY_FORUM_NAME));
}
}
}
...
}

How to get the average of a generic array list in java?

i'm having trouble getting the average of a generic array list of type T.
You should use <T extends Number> generic signature to specify the type of the Number types, plus, you should use instanceof keyword. A simple dummy demo here;
Test Code
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<Integer>();
List<Double> doubleList = new ArrayList<Double>();
List<Float> floatList = new ArrayList<Float>();
for(int i = 0; i < 10; i++)
{
integerList.add(new Integer(i+1));
doubleList.add(new Double(i+1));
floatList.add(new Float(i+1));
}
Utility<Integer> utilityInteger = new Utility<Integer>(integerList);
Utility<Double> utilityDouble = new Utility<Double>(doubleList);
Utility<Float> utilityFloat = new Utility<Float>(floatList);
System.out.println("Integer average: " + utilityInteger.getAverage());
System.out.println("Double average : " + utilityDouble.getAverage());
System.out.println("Float average : " + utilityFloat.getAverage());
}
public static class Utility<T extends Number>
{
// Fields
private List<T> list;
private Object average;
// Constructor
#SuppressWarnings("unchecked")
public Utility(List<T> list)
{
this.list = list;
T sample = list.get(0);
if(sample instanceof Double)
{
doAverageDouble((List<Double>) list);
}
else if (sample instanceof Integer)
{
doAverageInteger((List<Integer>) list);
}
else if (sample instanceof Float)
{
doAverageFloat((List<Float>) list);
}
else
{
throw new IllegalStateException("Constructor must be initialiez with either of Double, Integer or Float list");
}
}
// Methods
private void doAverageDouble(List<Double> list) {
Double sum = new Double(0);
for(Double d : list)
{
sum += d;
}
average = sum/new Double(list.size());
}
private void doAverageInteger(List<Integer> list) {
Integer sum = new Integer(0);
for(Integer d : list)
{
sum += d;
}
average = sum/new Integer(list.size());
}
private void doAverageFloat(List<Float> list) {
Float sum = new Float(0);
for(Float d : list)
{
sum += d;
}
average = sum/new Float(list.size());
}
Object getAverage()
{
return average;
}
}
}
Console Output
Integer average: 5
Double average : 5.5
Float average : 5.5

gwt cell table dynamic columns - sorting

You can represent your "rows" as List<String> instances, you have to change your parameterization from String to List in your Grid, Column and data provider; and of course you have to call updateRowData with a List<List<String>>, not a List<String>.
You also need one Column instance per column, taking the value out of the List by index:
class IndexedColumn extends Column<List<String>, String> {
private final int index;
public IndexedColumn(int index) {
super(new EditTextCell());
this.index = index;
}
#Override
public String getValue(List<String> object) {
return object.get(this.index);
}
}
How do i add sorting to this example. I tried a ListHandler but not sure how to compare List<String>. Any help is appreciated.
You need to add a ListHandler to each column you want to sort separately. Kind of like this:
You'll have to add a getter method to IndexedColumn for the index:
class IndexedColumn extends Column<List<String>, String> {
private final int index;
public IndexedColumn(int index) {
super(new EditTextCell());
this.index = index;
}
#Override
public String getValue(List<String> object) {
return object.get(this.index);
}
public int getIndex(){
return index;
}
}
Then you'll need to add a ListHandler to the CellTable:
ListHandler<List<String>> columnSortHandler = new ListHandler<List<String>>(list);
columnSortHandler.setComparator(columnName, new Comparator<List<String>>() {
public int compare(List<String> o1, List<String> o2) {
if (o1 == o2) {
return 0;
}
// Compare the column.
if (o1 != null) {
int index = columnName.getIndex();
return (o2 != null) ? o1.get(index).compareTo(o2.get(index)) : 1;
}
return -1;
}
});
table.addColumnSortHandler(columnSortHandler);
In the example above list is the List<List<String>> object. The columnName is the Column object. You'll have to do this for every column you want to sort.
Don't forget to also call .setSortable(true) on each of the columns that you will sort.
A good basic example of column sorting can be found here. The code above is based on this example but I used your index in IndexedColumn in order to get the proper String for the column to do the comparison.
Here is the data grid code
indexedColumn.setSortable(true);
sortHandler.setComparator((Column<T, ?>) indexedColumn, (Comparator<T>) indexedColumn.getComparator(true));
Here is the actual class
public class IndexedColumn extends Column<List<String>, String>
{
private Comparator<List<String>> forwardComparator;
private Comparator<List<String>> reverseComparator;
private final int index;
public IndexedColumn(int index)
{
super(new TextCell());
this.index = index;
}
#Override
public String getValue(List<String> object)
{
return object.get(index);
}
public Comparator<List<String>> getComparator(final boolean reverse)
{
if (!reverse && forwardComparator != null)
{
return forwardComparator;
}
if (reverse && reverseComparator != null)
{
return reverseComparator;
}
Comparator<List<String>> comparator = new Comparator<List<String>>()
{
public int compare(List<String> o1, List<String> o2)
{
if (o1 == null && o2 == null)
{
return 0;
}
else if (o1 == null)
{
return reverse ? 1 : -1;
}
else if (o2 == null)
{
return reverse ? -1 : 1;
}
// Compare the column value.
String c1 = getValue(o1);
String c2 = getValue(o2);
if (c1 == null && c2 == null)
{
return 0;
}
else if (c1 == null)
{
return reverse ? 1 : -1;
}
else if (c2 == null)
{
return reverse ? -1 : 1;
}
int comparison = ((String) c1).compareTo(c2);
return reverse ? -comparison : comparison;
}
};
if (reverse)
{
reverseComparator = comparator;
}
else
{
forwardComparator = comparator;
}
return comparator;
}
}

GWT Overlay deep copy

What is the best way to make a deep copy of a gwt overlay type?
I'm looking for a function or library that inspects a GWT overlay and clones it. It must be able to clone contained arrays or objects.
Thanks
There are 2 ways that I would consider. Most of the time overlay objects are used in conjunction with JSON, so you could just stringify the object and parse the results:
public native MyOverlayType deepCopy()/*-{
return JSON.parse(JSON.stringify(this));
}-*/;
OR
public static native MyOverlayType fromJson(String json)/*-{
return JSON.parse(json);
}-*/;
public native String getJson()/*-{
return JSON.stringify(this);
}-*/;
public MyOverlayType deepCopy(){
return fromJson(getJson());
}
The other option is a pure javascript approach which will maintain other stuff such as function pointers and probably be more efficient.
public class JsoUtils
{
#SuppressWarnings("unchecked")
public static <T extends JavaScriptObject> T deepCopy(T obj)
{
return (T) deepCopyImpl(obj);
}
private static native JavaScriptObject deepCopyImpl(JavaScriptObject obj)/*-{
if (typeof obj !== 'object' || obj === null) {
return obj;
}
var c = obj instanceof Array ? [] : {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (typeof obj[i] !== 'object' || obj[i] === null)
c[i] = obj[i];
else
c[i] = #com.example.gwt.client.JsoUtils::deepCopyImpl(Lcom/google/gwt/core/client/JavaScriptObject;)(obj[i]);
}
}
return c;
}-*/;
}
Based on Lineman78's answer and taking into consideration this other answer from A. Levy I created the following function:
public class JsoUtils {
#SuppressWarnings("unchecked")
public static <T extends JavaScriptObject> T deepCopy(T obj)
{
return (T) deepCopyImpl(obj);
}
private static native JavaScriptObject deepCopyImpl(JavaScriptObject obj) /*-{
if (obj == null) return obj;
var copy;
if (obj instanceof Date) {
// Handle Date
copy = new Date();
copy.setTime(obj.getTime());
} else if (obj instanceof Array) {
// Handle Array
copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
if (obj[i] == null || typeof obj[i] != "object") copy[i] = obj[i];
else copy[i] = #com.amindea.noah.client.utils.JsoUtils::deepCopyImpl(Lcom/google/gwt/core/client/JavaScriptObject;)(obj[i]);
}
} else {
// Handle Object
copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) {
if (obj[attr] == null || typeof obj[attr] != "object") copy[attr] = obj[attr];
else copy[attr] = #com.amindea.noah.client.utils.JsoUtils::deepCopyImpl(Lcom/google/gwt/core/client/JavaScriptObject;)(obj[attr]);
}
}
}
return copy;
}-*/;
}
It supports deep copy of Object, Array, Date, String, Number, or Boolean. As explained by A. Levy the function will work as long as the data in the objects and arrays form a tree structure.
I found the simplest way to clone a JavaScriptObject is using the JsonUtils class provided by GWT:
import com.google.gwt.core.client.JsonUtils;
final String taskJson = JsonUtils.stringify(selectedTask);
TaskJso task = JsonUtils.safeEval(taskJson).cast();