java.lang.IllegalArgumentException: Comparison method violates its general contract (sorting) - comparison

I have an exception when I want to sort my alert list. I know that there are some people who have asked the same question with me. But I really don't have any idea which part of my code causing this exception.
Below is my coding part for sorting the alert list:
Collections.sort(listAlert, new Comparator()
{
public int compare(Object o1, Object o2)
{
int i = ((Alert)o1).getAlertType().compareTo(((Alert)o2).getAlertType());
if(i == 0)
{
return (int)(((Alert)o1).getTime() - ((Alert)o2).getTime());
}
else return i;
}
});
Note: getAlertType() method will return the alert type in String and getTime() method will return the alert creation date in millisecond (long)
I really need you help.
TIA,
Tenlee

Related

Dart best practice to return null from RangeError (index)

What is the best practice to return null for:
Unhandled exception: RangeError (index): Invalid value: Not in inclusive range 0..2
My code:
late final int? element;
try {
element = l[index];
} catch(e) {
element = null;
}
Looking for a shorter, one-liner solution.
Something like:
final element = l[index] ?? null;
The best practice for errors is to not throw them.
In this case, I'd do:
final T? element = (index >= 0 && index < l.length) ? l[index] : null;
No need for late, not throwing or catching errors.
If an error does get thrown, it's probably a real error in the program.
If you catch and ignore errors that you expect, you risk also catching errors you didn't expect, and hiding real problems. That's the real reason catching errors as part of "normal control flow" is frowned upon, not just because less efficient. Which it also is.
And it's why you should always throw (and document) precise types of exceptions from an API, so that the user can do precise catches.
Hope this answer can satisfy you. :)
final int? element = (index == null || index.clamp(0,l.length - 1) != index) ? null : l[index];
you can use extension method :
myextension.dart :
extension NullableList<T> on List<T> {
T? nullable(int index){
T? element;
try {
element = this[index];
} catch(_) {
}
return element;
}
}
use it :
homepage.dart :
List<int> l = [1];
int? result = l.nullable(3);
print(result); //--> null
print(l.nullable(0)); //--> 1

Safe way to access List index

I'm newbee to Dart.
I have troubles to find an easy to read way to "safely" access a List element at any index
final List<String> myList = <String>[]
myList.add("something")
// ...
String myGetter(int index) {
// "heavy" way
if (index < myList.length) {
return myList[index]
}
return null;
}
If I go with regular [index] or elementAt(index) and index is out of boundaries, it throws a RandeError
Is there a method that returns null when the index cannot be reached?
Sorry if double posted, but I try to find the info without any success, + not sure if there is an (un)official slack / discord to ask this kind of "easy" questions
Dart lists do not allow invalid indices. There is no built-in way to get a null when trying. Not in the platform libraries.
You can create your own helper function (like you already do):
T? tryGet<T>(List<T> list, int index) =>
index < 0 || index >= list.length ? null : list[index];
(Remember to check for negative indices too).
As suggested, you can also add it as an extension method:
extension ListGetExtension<T> on List<T> {
T? tryGet(int index) =>
index < 0 || index >= this.length ? null : this[index];
}
which may make it more pleasant to work with.
(I recommend against doing something bad and then catching the error, at least when you can easily check up-front whether it's bad or not).
You can defined an extension method to catch the RangeError and return null:
void main() {
print([1, 2].get(3)); // display null
}
extension SafeLookup<E> on List<E> {
E get(int index) {
try {
return this[index];
} on RangeError {
return null;
}
}
}
You can try this
void main() {
List<int> teste = [1, 2, 3, 4];
print(teste.get(1));
}
extension ListExtension<E> on List<E> {
dynamic get(int value) {
return this.contains(value) ? value : null;
}
}
According to the documentation:
throws a RangeError if index is out of bounds.
So you can use the try-catch block:
String myGetter(int index) {
try {
return myList[index];
}
on RangeError {
// Called when the index is out of bounds
return null;
}
}
If you want to be extra cautious I guess you could put a generic catch at the end (to catch all kinds of throws that are not RangeError), but in a simple getter like this I think that would not be necessary:
[...]
}catch (e) {
// No specified type, handles all other types of error/exceptions
return null;
}
[...]

Where is the SequenceRange from the walk-method from ExtendedDataModel defined?

The ExtendedDataModel from ajax4jsf uses a method called walk, looking like this:
public void walk(FacesContext ctx, DataVisitor dv, Range range, Object argument){}
This method is called several times in my application. Some topics on internet seem to say that it the latter is defined by the rows="x" in the xhtml. However, for me range is always defined as 0 (firstRow) - -1 (getRows).
So I was wondering where this range is defined, so I can figure out why the wrong parameters are passed to it. Debugging and googling hasn't helped me so far.
Range represents visible part of data displayed in table. If you have paginator, then paginator display which page (= from which row to which row) data is presented.
Problem can be in incorrect value of rows attribute of data table (for example rows attribute is missing).
Other place can be in incorrect implementation of data model. Object of data model class can be used as storage for data displayed in rich:dataTable.
Real example:
public class VSDataModel<RecordType> extends ExtendedDataModel<RecordType> implements Arrangeable {
private final FetchList<RecordType> list;
#Override
public void walk(FacesContext ctx, DataVisitor visitor, Range range, Object obj) {
try {
int firstRow = ((SequenceRange) range).getFirstRow();
int numberOfRows = ((SequenceRange) range).getRows();
if(list == null) {
throw new RuntimeException("Underlying list is null!");
}
if(list.getList() == null || firstRow != list.getFirstRow()) {
list.fetch(firstRow, numberOfRows);
}
for (RecordType elem : list.getList()) {
visitor.process(ctx, list.getPK(elem), obj);
}
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
It is used in Java private VSDataModel<Record> dependentList; and html
<rich:dataTable value="#{bean.dependentList}" rows="#{referenceData.recordsPerPage}">

Method declaration in java

I have a question regarding this code, you can see in some methods that there are comments with a return, that is because I think I have to use a return method instead of a void method. My teacher told me to transform them to a void class, but isn't a method which modifies field variables suposed to return something? I'm in doubt because sometimes my teacher seems to not know so much about programming or has some doubts so, thank for your help beforehand.
public class ArraysClass {
private int[] array;
private int arrayLength;
public ArraysClass() {
setArrayLength();
array = new int[arrayLength];
}
public int setArrayLength() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a number to set the length of the array:");
arrayLength = scanner.nextInt();
System.out.println();
return arrayLength;
}
public void fillArray() {
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < arrayLength; i++) {
System.out.println("Type a number to fill position " + i);
array[i] = scanner.nextInt();
}
// return array;
System.out.println();
}
public void findNumber() {
Scanner scanner = new Scanner(System.in);
int tofind, position;
System.out.println("Enter a number to search it in the array:");
tofind = scanner.nextInt();
position = Arrays.binarySearch(array, tofind);
if (position < 0) {
System.out.println("We did not find your number.");
} else {
System.out.println("The number you typed is in the next position: " + position);
}
System.out.println();
}
public void fillMethod() {
Scanner scanner = new Scanner(System.in);
int tofill;
System.out.println("Enter a number to fill the entire array with:");
tofill = scanner.nextInt();
Arrays.fill(array, tofill);
System.out.println();
//return array;
}
public void Sortmethod() {
Arrays.sort(array);
//return array;
}
private void showArray() {
System.out.println("Showing the array...");
for (int i = 0; i < arrayLength; i++) {
System.out.println(array[i]);
}
System.out.println();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArraysClass arrayobj = new ArraysClass();
int choose;
do {
do {
System.out.println("1-Fill the array");
System.out.println("2-Find a number in the array");
System.out.println("3-Fill the entire array with a number");
System.out.println("4-Sort the array");
System.out.println("5-Show the array");
System.out.println("6-Exit");
System.out.println("Which one do you want to use?:");
choose = scanner.nextInt();
} while (choose < 1 && choose > 6);
switch (choose) {
case 1:
arrayobj.fillArray();
break;
case 2:
arrayobj.findNumber();
break;
case 3:
arrayobj.fillMethod();
break;
case 4:
arrayobj.Sortmethod();
break;
case 5:
arrayobj.showArray();
break;
case 6:
break;
}
} while (choose != 6);
}
}
In general, a method should return something if you need value from it. It is an approach used by some programmers to return a boolean even for do-only methods for success or failure or an int, for a status code. I do not follow these approaches. When I implement a method, I always ask myself how would I like to use that method. If I need a value from it, then it will have its type. Otherwise, it will be void. Let us see your methods:
setArrayLength: In general, from this name I would expect that you pass an int to it, representing the length and the method to be void. This is very common for setters, but here you are reading the actual value inside the method which is clearly inferior compared to having an int parameter, as your method will be useless if one wants to set the array length using a value not read from the console.
fillArray: I would expect this to be void, so I agree with its declaration, but again, the reading part should not be here.
findNumber: Should get the number to be found as a parameter and return an int, which represents its index, -1 if not found.
fillMethod: Should be void and should have an int parameter, which represents the value to be used to fill the array.
sortMethod: ok, maybe return the resulting array, but depends on your needs.
showArray: I would expect a PrintStream there, you will not necessarily output to System.out
General mistake: You mix methods with in/out operations to the console, the code is not general enough this way.

How to make Range work with foreach statement

I have the following range:
struct Range {
uint data;
#property{
bool empty() { return false; }
uint front() { return data; }
void popFront() { data = data * 2 + 1; }
}
}
Trying to use it,
foreach(c; Rnage()){ /*...*/ } works, but with foreach(i, c; Range()){ /*...*/ } I get:
Error: cannot infer argument types
I need the i just like in something like foreach(i, v; [1,2,3,4]){ }.
Ranges do not support the syntax
foreach(i, c; range)
While it seems obvious that that should work in the simple case, what that index should even be depends on the type of range and doesn't always make sense. So, no counter for the index is provided automatically by foreach, and a range has no way of providing one.
However, thanks to tuple unpacking with foreach, you can do it by using std.range.sequence std.range.zip with your range:
foreach (i, e; zip(sequence!"n"(), range))
{
}
By the way, you shouldn't mark popFront with #property. It doesn't make any sense. popFront takes no arguments and returns no value. It does not act like a variable at all. And the point of properties is to have functions which act like variables. If/when -property's implementation is fully sorted out and it becomes the normal behavior (it's rather buggy at the moment, which is part of why it's a separate switch for the moment), popFront would not be usable as you defined it.
If you use opApply to implement the range, You can overload one version for the without-index style and for the with-index style:
struct Range {
int opApply(int delegate(int) action){
uint data=0;
while(true){
action(data);
data=data*2+1;
}
return 0;
}
int opApply(int delegate(uint,int) action){
uint i=0;
foreach(element;this){
action(i++,element);
}
return 0;
}
}

Resources