I have to make an especific sort in a object. I read a lot of tutorials and utilized the class Comparable.
My Class:
public class PaAcao implements Serializable, IAcao, Comparable<PaAcao> /* Ordenar */ {
#Override
public int compareTo(PaAcao acaoCompara) {
//return this.aresta - outro.aresta;
int i = 0;
String[] array1 = this.cnrAcao.split(".");
String[] array2 = acaoCompara.cnrAcao.split(".");
for(String c : array1){
if (array2.length > i){
if (Integer.parseInt(c) > Integer.parseInt(array2[i]))
{
return 1;
}
if (Integer.parseInt(c) < Integer.parseInt(array2[i]))
{
return -1;
}
}
i++;
}
return -1;
}
For this Class i have an interface:
package br.com.agraria.qualidade.model.entity;
public interface IAcao{
public abstract String getCnmUsuarResp();
public abstract Usuario getusuarResp();
public abstract void setusuarResp(Usuario usuarResp);
public abstract PaStatusAcao getIcdStatus();
public abstract String getCnrAcao();
public abstract Boolean getLpublico();
}
And i get the error below:
public class PaAcaoServiceImpl extends HibernateGenericServiceImpl<PaAcao> implements PaAcaoService {
#Override
public List<? extends IAcao> processarAcoes(List<? extends IAcao> acoesProcessar) {
SessaoPrivilegiosGerente sessaoPrivilegiosGerente = sessaoService.getSessaoPrivilegiosGerente();
List<IAcao> macroRemover = new ArrayList<IAcao>();
Collections.sort(acoesProcessar);
...
}
}
The problem is in the line Collections.sort(acoesProcessar);
I get the message:
Bound mismatch: The generic method sort(List<T>) of type Collections
is not applicable for the arguments (List<capture#14-of ? extends IAcao>). The inferred type capture#14-of ? extends IAcao is not a
valid substitute for the bounded parameter <T extends Comparable<? super T>>
The resolution was (Thanks Deactivator2 for helping me with this):
Extends Comparable on the interface IAcao:
package br.com.agraria.qualidade.model.entity;
public interface IAcao extends Comparable<IAcao>{
public abstract String getCnmUsuarResp();
public abstract Usuario getusuarResp();
public abstract void setusuarResp(Usuario usuarResp);
public abstract PaStatusAcao getIcdStatus();
public abstract String getCnrAcao();
public abstract Boolean getLpublico();
}
And in my class PaAcao, I remove the implements of Comparable because it'll be duplicated and change the type os compareTo to IAcao and not PaAcao:
public class PaAcao implements Serializable, IAcao /* Ordenar */ {
#Override
public int compareTo(IAcao acaoCompara) {
//return this.aresta - outro.aresta;
int i = 0;
String[] array1 = this.cnrAcao.split(".");
String[] array2 = acaoCompara.cnrAcao.split(".");
for(String c : array1){
if (array2.length > i){
if (Integer.parseInt(c) > Integer.parseInt(array2[i]))
{
return 1;
}
if (Integer.parseInt(c) < Integer.parseInt(array2[i]))
{
return -1;
}
}
i++;
}
return -1;
}
Related
How can I create abstract generic method doSomething() that accepts different enums? Enum1 and Enum2, Enum3 and so on?
public abstract class NumerOne {
public abstract void doSomething();
}
public class NumberTwo extends NumberOne {
#Override
public void doSomething (Enum1 enum1) {
enum1.createSomething();
}
The most appropriate way to accept a handful of Enum types, but not accept any enum (<T extends Enum<T>) or (even worse) Object would be to create an interface and have all the enums that you want to accept implement that interface:
interface CreatorOfSomething {
// I have no idea what type should be returned here,
// as you don't use this value in your example.
// But I'm pretty sure it can't be void, so I'll go with Integer.
// You can have this parameterised as <T> at the interface level.
Integer createSomething();
}
enum Enum1 implements CreatorOfSomething {
A, B, C;
#Override
public Integer createSomething() {
return ordinal();
}
}
enum Enum2 implements CreatorOfSomething {
X { // you can override the method for individual constants
#Override
public Integer createSomething() {
// .....
}
},
Y { ....
}
Then your method would look like:
public void doSomething(CreatorOfSomething creator) {
creator.createSomething();
}
The code you posted does not even compile. Nor could we run it. Next time please provide an SSCCE in which you address your question.
Here's the solution for the problem you have:
abstract class NumberOne {
public abstract <T extends Enum<T>> void doSomething(T pEnum);
}
enum Enum1 {
A, B
}
enum Enum2 {
C, D
}
public class NumberTwo extends NumberOne {
#Override public <T extends Enum<T>> void doSomething(final T pEnum) {
System.out.println("Value: " + pEnum);
}
public static void main(final String[] args) {
final NumberTwo n2 = new NumberTwo();
n2.doSomething(Enum1.A);
n2.doSomething(Enum2.D);
}
}
Just need some help with this error in code:
interface ParticleId{
int getX();
}
class ParticleId1 implements ParticleId{
int a;
#Override
public int getX() {
return a;
}
}
class ParticleId2 implements ParticleId{
int a,b;
#Override
public int getX() {
return a+b;
}
}
interface ParticleInt<K extends ParticleId, O extends ParticleInt<K, O>>{
O withSmt();
}
class Particle<K extends ParticleId> implements ParticleInt<K, Particle<K>>{
#Override
public Particle<K> withSmt() {
return new Particle<>();
}
}
class Particle2<K extends ParticleId> extends Particle<K>{
#Override
public Particle2<K> withSmt() {
return new Particle2<>();
}
}
interface Executable<P extends Particle<? extends ParticleId>>{
void setExecutableStrategy(ExecutableStrategy<P> s);
}
interface ExecutableStrategy<P extends Particle<? extends ParticleId>>{
Stream<P> exec(List<P> l);
}
class Particle2Strat implements ExecutableStrategy<Particle2<? extends ParticleId>>{
#Override
public Stream<Particle2<? extends ParticleId>> exec(List<Particle2<? extends ParticleId>> l) {
return l.stream().map(x -> x.withSmt());
}
}
class ParticleStrat<P extends Particle<? extends ParticleId>> implements ExecutableStrategy<P>{
#Override
public Stream<P> exec(List<P> l) {
return l.stream().map(x -> x.withSmt());
// [44,38] incompatible types: inference variable R has incompatible bounds
// equality constraints: P
// [ERROR] lower bounds: Particle<capture#1 of ? extends ParticleId>
}
}
The error is shown on the end of the code, and exact description is [44,38] incompatible types: inference variable R has incompatible bounds. equality constraints: P. [ERROR] lower bounds: Particle<capture#1 of ? extends ParticleId>.
Quick fix that I found working is just manually casting lambda to (P) like (P)x.withSmt(). Anybody knows more proper way to fix this if possible at all?
I just updated the code so it is not using anymore Integer but ParticleId interface.
UPDATE
After update I now have this problem:
class ParticleStrat<P extends ParticleId> implements ExecutableStrategy<Particle<P>>{
#Override
public Stream<Particle<P>> exec(List<Particle<P>> l) {
return l.stream().map(x -> x.withSmt()); //OK NOW
}
}
class MainExecutable<P extends Particle<? extends ParticleId>> implements Executable<P>{
private ExecutableStrategy<P> s;
public MainExecutable() {
this.s = new ParticleStrat<>();
//incompatible types: cannot infer type arguments for ParticleStrat<>
//no instance(s) of type variable(s) P exist so that ParticleStrat<P> conforms to ExecutableStrategy<P>
}
#Override
public void setExecutableStrategy(ExecutableStrategy<P> s) {
this.s = s;
}
}
Changing the declaration of ParticleStrat class to the following solves the compilation error:
class ParticleStrat<P extends ParticleInt<P>> implements ExecutableStrategy<P>{
#Override
public Stream<P> exec(List<P> l) {
return l.stream().map(x -> x.withSmt());
}
}
This way x.withSmt() is guaranteed to return P.
EDIT following the change in your question:
This passes compilation:
class ParticleStrat<K extends Integer> implements ExecutableStrategy<Particle<K>>{
#Override
public Stream<Particle<K>> exec(List<Particle<K>> l) {
return l.stream().map(x -> x.withSmt());
}
}
And after your latest update:
class ParticleStrat<K extends ParticleId> implements ExecutableStrategy<Particle<K>>{
#Override
public Stream<Particle<K>> exec(List<Particle<K>> l) {
return l.stream().map(x -> x.withSmt());
}
}
As for your latest problem, the same approach can work:
class MainExecutable<K extends ParticleId> implements Executable<Particle<K>>{
private ExecutableStrategy<Particle<K>> s;
public MainExecutable() {
this.s = new ParticleStrat<>();
}
#Override
public void setExecutableStrategy(ExecutableStrategy<Particle<K>> s) {
this.s = s;
}
}
I have abstract class OptionalComparator<T extends Comparable<T>> implements Comparator<Optional<T>>
So far, so good.
Following the model used by Optional itself, I figured it would be best to have a single instance of this class, and cast it when necessary (for example, to OptionalComparator<Integer>).
So I made private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST.
The trouble came when I tried to assign a value. What should the type be?
new OptionalComparator<Comparable<Object>>() {...} doesn't work.
new OptionalComparator<Comparable<Comparable<Object>>>() {...} doesn't work.
new OptionalComparator<Integer>() {...} does work, for example, but I want the least-specific type possible.
What am I doing wrong? How can I make a base-case instance of this class?
You can have multiple implementations of OptionalComparator like this:
private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST = new AbsentFirst<>();
private static final OptionalComparator<? extends Comparable<?>> ABSENT_LAST = new AbsentLast<>();
private interface OptionalComparator<T extends Comparable<T>> extends Comparator<Optional<T>> { }
private static class AbsentFirst<T extends Comparable<T>> implements OptionalComparator<T> {
#Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return -1;
} else if (obj2.isPresent()) {
return 1;
} else {
return 0;
}
}
}
private static class AbsentLast<T extends Comparable<T>> implements OptionalComparator<T> {
#Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return 1;
} else if (obj2.isPresent()) {
return -1;
} else {
return 0;
}
}
}
static <T extends Comparable<T>> OptionalComparator<T> absentFirstComparator() {
#SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_FIRST;
return comp;
}
static <T extends Comparable<T>> OptionalComparator<T> absentLastComparator() {
#SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_LAST;
return comp;
}
public static void main(String... args) {
OptionalComparator<Integer> absentFirstInt = absentFirstComparator();
System.out.println(absentFirstInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Integer> absentLastInt = absentLastComparator();
System.out.println(absentLastInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Double> absentFirstDouble = absentFirstComparator();
System.out.println(absentFirstDouble.compare(Optional.of(1.0), Optional.empty()));
OptionalComparator<Double> absentLastDouble = absentLastComparator();
System.out.println(absentLastDouble.compare(Optional.of(1.0), Optional.empty()));
}
Output:
-1
1
-1
1
Guava now provides (since 21.0, and no more #Beta since 27.1) Comparators.emptiesLast(Comparator) and emptiesFirst(Comparator).
Example: Comparator<Optional<Instant>> compareOptInst = Comparators.emptiesLast(Comparator.naturalOrder());
You may just have to do an unsafe cast. Consider how ImmutableList handles the empty-list case:
private static final ImmutableList<Object> EMPTY =
new RegularImmutableList<Object>(ObjectArrays.EMPTY_ARRAY);
/**
* Returns the empty immutable list. This set behaves and performs comparably
* to {#link Collections#emptyList}, and is preferable mainly for consistency
* and maintainability of your code.
*/
// Casting to any type is safe because the list will never hold any elements.
#SuppressWarnings("unchecked")
public static <E> ImmutableList<E> of() {
return (ImmutableList<E>) EMPTY;
}
In this case, it might similarly be easiest to use a raw type instance. As long as you gate all calls that return ABSENT_FIRST with generic casts, this will be fine, and calling code shouldn't have any warnings.
I have the following code:
public interface IDoWork<K extends AbstractKey,V extends AbstractClass> {
V obtain(K key, V value);
}
public class AbstractKey {
String id;
}
public class AbstractClass {
String name;
}
public class ConcreteA extends AbstractClass {
String attributeA;
}
public class DoWorkA implements IDoWork<KeyA, ConcreteA> {
private static final DoWorkA INSTANCE = new DoWorkA();
public static DoWorkA getInstance() {
return INSTANCE;
}
#Override
public ConcreteA obtain(KeyA k, ConcreteA v) {
//do something in real life
return null;
}
}
public class Main {
public static void main(String[] args){
KeyA a = new KeyA();
ConcreteA c = new ConcreteA();
IDoWork<? extends AbstractKey, ? extends AbstractClass> instance =
WorkFactory.getInstance().obtainInstance(a);
instance.obtain(a, c);
}
}
public class WorkFactory {
private static final WorkFactory INSTANCE = new WorkFactory();
public static WorkFactory getInstance() {
return INSTANCE;
}
public IDoWork<? extends AbstractKey, ? extends AbstractClass> obtainInstance(AbstractKey key){
if(key instanceof KeyA){
return DoWorkA.getInstance();
}
throw new IllegalArgumentException("Case not handled");
}
}
In the following code:
KeyA a = new KeyA();
ConcreteA c = new ConcreteA();
IDoWork<? extends AbstractKey, ? extends AbstractClass> instance = WorkFactory.getInstance().obtainInstance(a);
instance.obtain(a, c);
This line doesn't compile:
instance.obtain(a, c);
due to the nature of Java generics. I get the following error:
The method obtain(capture#3-of ? extends AbstractKey, capture#4-of ? extends AbstractClass) in the type IDoWork is not applicable for the arguments (KeyA, ConcreteA)
Is there another way to do it? If omit the type parameters in
IDoWork<? extends AbstractKey, ? extends AbstractClass> instance =...
If I remove the type parameters from IDoWork... it works but I get a warning. Is there a way to fix that.? I know that I can remove the type parameters from the interface and that will solve the problem but I find it handy to have the generics in order not to have to do casting + it brings clarity to the code since it's clear to see what each class uses. Depencendy injection is out of question because it's not available in the codebase I'm in.
I have something that works, but is not very optimal:
If you define your WorkFactory this way:
public class WorkFactory {
private static final WorkFactory INSTANCE = new WorkFactory();
public static WorkFactory getInstance() {
return INSTANCE;
}
#SuppressWarnings("unchecked")
public <K extends AbstractKey, V extends AbstractClass> IDoWork<K, V> obtainInstance(K key, V val) {
if (key instanceof KeyA) {
return (IDoWork<K, V>) DoWorkA.getInstance();
}
throw new IllegalArgumentException("Case not handled");
}
}
then your main method should work cleanly:
public static void main(String[] args){
KeyA a = new KeyA();
ConcreteA c = new ConcreteA();
IDoWork<KeyA, ConcreteA> instance = WorkFactory.getInstance().obtainInstance(a, c);
instance.obtain(a, c);
}
I have changed obtainInstance to take the key and the val, to infer the types properly.
class Collator<S extends Stream<E extends Comparable<E>>> {
S s;
E e;
public <S> Collator(List<S> streams){
s = streams.get(0);
e = s.read();
}
public <E> E next(){
return e;
}
}
interface Stream<E extends Comparable<E>>{
public E read();
}
class Record implements Comparable<Record>{
public Integer time;
public int compareTo(Record r){
return this.time.compareTo(r.time);
}
}
Especially 1st line:
class Collator<S extends Stream<E extends Comparable<E>>>
I expect to say:
Define a collator that works on Streams of Entries where each Entry implements comparable.
you miss-qualified the generic parameters
class Collator<S extends Stream<E>,E extends Comparable<E>> {
S s;
E e;
public Collator(List<S> streams){
s = streams.get(0);
e = s.read();
}
public E next(){
return e;
}
}
interface Stream<E extends Comparable<E>>{
public E read();
}
class Record implements Comparable<Record>{
public Integer time;
public int compareTo(Record r){
return this.time.compareTo(r.time);
}
}
this compiles
in particular the line class Collator<S extends Stream<E>,E extends Comparable<E>> it means a Collator that works on a S that is a Stream of E and E implement Comparable
Some glass ball guessing, since you don't show your error message:
Your constructor and method are declaring new type parameters <E> and <S> which are shadowing the type parameters of your class. Remove them.
Then, E should be a type parameter of your class, too.
class Collator<E extends Comparable<E>, S extends Stream<E>> {
S s;
E e;
public Collator(List<S> streams){
s = streams.get(0);
e = s.read();
}
public E next(){
return e;
}
}
interface Stream<E extends Comparable<E>>{
public E read();
}
class Record implements Comparable<Record>{
public Integer time;
public int compareTo(Record r){
return this.time.compareTo(r.time);
}
}
The problem is E extends Comparable
Define a collator that works on Streams of Entries where each Entry implements comparable of a given type:
public class Collator<T,E extends Comparable<T>, S extends Stream<E>>