Problem z implementacją klasy Optional

0

Witam,
mam problem z następującym programem:

public class Main {

	@SuppressWarnings({ "unchecked"})
	public static void test() {
		// Metoda of(...)
		String s = "aaa";
		Maybe<String> m1 = Maybe.of(s);
		System.out.println(m1);
		s = null;
		Maybe<String> m2 = Maybe.of(s);
		System.out.println(m2);

		// Metoda ifPresent(...)
		Integer num = null;
		@SuppressWarnings("unchecked")
		Maybe<Integer> m4 = Maybe.of(num);
		if (num != null)
			System.out.println(num);
		m4.ifPresent(n -> System.out.println(n));
		m4.ifPresent(System.out::println);

		Maybe<Integer> m5 = Maybe.of(10);
		m5.ifPresent(System.out::println);

		// Metoda map()
		Maybe<Integer> m6 = m5.map(n -> n + 10);
		System.out.println(m6);

		// Metoda get()
		System.out.println(m6.get());
		try {
			System.out.println(m4.get());
		} catch (Exception exc) {
			System.out.println(exc);
		}

		// Metoda orElse()
		String snum = null;
		if (num != null)
			snum = "Wartość wynosi: " + num;
		if (snum != null)
			System.out.println(snum);
		else
			System.out.println("Wartość niedostępna");

		String res = Maybe.of(num).map(n -> "Wartość wynosi: " + n).orElse("Wartość niedostępna");
		System.out.println(res);

		// I filter(...)

		String txt = "Pies";
		String msg = "";

		if (txt != null && txt.length() > 0) {
			msg = txt;
		} else {
			msg = "Txt is null or empty";
		}

		msg = Maybe.of(txt).filter(t -> t.length() > 0).orElse("Txt is null or empty");
		System.out.println(msg);
	}

	public static void main(String[] args) {
		test();
	}
}
```
program ma zwraca następujący wynik na konsoli:

 Maybe has value aaa Maybe is empty 10 Maybe has value 20 20
 java.util.NoSuchElementException: maybe is empty Wartość niedostępna Wartość
 niedostępna Pies

oraz klasa Maybe:
``````java
import java.util.NoSuchElementException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

public class Maybe<T> {
	Maybe m;
	T t;

	public Maybe() {
		m = new Maybe();
	}

	public Maybe(T t) {
		this.SetParam(t);
	}

	public static <T> Maybe<T> of(T t){
		Maybe<T> maybe = new Maybe<>();
		maybe.setParam(t);
		return maybe;
		}

	private void setParam(T t) {
		t = this.t;
	}

	public void ifPresent(Consumer cons) {
		if (m != null) {
			cons.accept(m);
		} else {

		}
	}

	<R> Maybe<R> map(Function<T, R> func) {
		if (t != null)
			return new Maybe<R>(func.apply(t));
		return new Maybe<R>(null);
	}

	public T get() {
		if (m == null) {
			throw new NoSuchElementException();
		} else {
			return t;
		}
	}

	public boolean isPresent() {
		if (m != null) {
			return true;
		} else {
			return false;
		}
	}

	public T orElse(T defVal) {
		if (m == null) {
			return defVal;
		} else {
			return t;
		}
	}

	public Maybe filter(Predicate pred) {
		if (pred.test(pred) == true) {
			return m;
		} else {
			m = new Maybe();
			return m;
		}
	}
}
```
Przy próbie kompilacji, otrzymuje dwa błędy przy kompilacji linii 
```java
msg = Maybe.of(txt).filter(t -> t.length() > 0).orElse("Txt is null or empty");
```
The method length() is undefined for the type Object oraz Type mismatch: cannot convert from Object to String
0

Musisz doczytać o generykach, w tym co to znaczy kowariancja i kontrawariancja, bo robisz to bardzo dziwne wszystko. Predicate bez parametru będzie zakładał że parametrem jest object.
To co musisz zrobić to napisać:

public Maybe filter(Predicate<? super E> predicate) {
//reszta kodu
}

Oznacza to że predicate może operować na dowolnym obiekcie ograniczonym z dołu przez np. Stringa jeśli String będzie parametrem.
Dwie sprawy poboczne:
1)zamiast T powinien byc E, to standardowa litera w Javie do klas generycznych typu kontenery
2)Maybe m; po co? Stosujesz jakieś bardziej dziwne konstrukcje

0

ok, dzięki

0

@Aravil: tu masz (częściową, bo mapowania jeszcze nie zrobiłem) implementacje takiej klasy:
Jednak powinno być T zamiast E bo to nie kolekcja. Ale za zadanie domowe masz się dowiedziec co to znaczy <? super T> i <? extends T>


public final class Maybe<T> {

  private final T value;

  public static <T> Maybe<T> empty() {
    return new Maybe<>(null);
  }

  public static <T> Maybe<T> of(T value) {
    return new Maybe<>(value);
  }

  private Maybe(T value) {
    this.value = value;
  }

  public boolean isEmpty() {
    return value == null;
  }

  public boolean isPresent() {
    return value != null;
  }

  public T get() {
    if (isEmpty()) {
      throw new NoSuchElementException();
    }
    return value;
  }

  public T orElse(T defaultValue) {
    if (isPresent()) {
      return value;
    } else {
      return defaultValue;
    }
  }

  public T orElseGet(Supplier<? extends T> defaultValueSupplier) {
    if (isPresent()) {
      return value;
    } else {
      return defaultValueSupplier.get();
    }
  }

  public T orElseThrow(Supplier<? extends RuntimeException> exceptionSupplier) {
    if (isPresent()) {
      return value;
    }
    throw exceptionSupplier.get();
  }

  public Maybe<T> filter(Predicate<? super T> predicate) {
    Objects.requireNonNull(predicate);
    if (isEmpty()) {
      return this;
    } else {
      if (predicate.test(value)) {
        return this;
      }
      return empty();
    }
  }

  public boolean equals(Object object) {
    if (this == object) {
      return true;
    } else if (object == null) {
      return false;
    } else if (!(object instanceof Maybe)) {
      return false;
    } else {
      Maybe maybe = (Maybe) object;
      return Objects.equals(value, maybe.value);
    }
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(value);
  }

  @Override
  public String toString() {
    if (isEmpty()) {
      return "Maybe.empty";
    } else {
      return "Maybe[" + value + "]";
    }
  }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1