Is there any simple way to reduce the lines of code to print the innermost not null object using Optional as alternative to the below code. I feels like we have to write more lines of code to avoid the null checks now.
Is there any easy way to make this code short and sweet in Java 8?
import java.util.Optional;
public class OptionalInnerStruct {
public static void main(String[] args) {
// creepy initialization step, dont worry
Employee employee = new Employee();
employee.setHuman(Optional.empty());
// with optional
Optional<Human> optionalHuman = employee.getHuman();
if (optionalHuman.isPresent()) {
Human human = optionalHuman.get();
Optional<Male> optionalMale = human.getMale();
if (optionalMale.isPresent()) {
Male male = optionalMale.get();
Optional<Integer> optionalAge = male.getAge();
if (optionalAge.isPresent()) {
System.out.println("I discovered the variable finally " + optionalAge.get());
}
}
}
// without optional in picture, it will be something like:
/*if(null! = employee.getHuman() && null!= employee.getHuman().getMale() && null! = employee.getHuman().getMale().getAge()) {
System.out.println("So easy to find variable " + employee.getHuman().getMale().getAge());
}*/
}
static class Employee {
Optional<Human> human;
public Optional<Human> getHuman() {
return human;
}
public void setHuman(Optional<Human> human) {
this.human = human;
}
}
class Human {
Optional<Male> male;
public Optional<Male> getMale() {
return male;
}
public void setMale(Optional<Male> male) {
this.male = male;
}
}
class Male {
Optional<Integer> age;
public Optional<Integer> getAge() {
return age;
}
public void setAge(Optional<Integer> age) {
this.age = age;
}
}
}
You can use Optional.flatMap here
employee.getHuman()
.flatMap(Human::getMale)
.flatMap(Male::getAge)
.ifPresent(age -> System.out.println("I discovered the variable finally " + age);
I want to, within my abstract class, define two constructors.
When create a new instance of the class, i want the toString to return something different depending on what was called:
The FireEngine Class
public class FireEngine extends EmergencyVehicle {
private String colour;
public FireEngine(String colour) {
super (colour);
}
public FireEngine() {
this("red");
}
public String toString () {
if (colour == "red") {
return "red";
} else
return "no";
}
}
The EmergencyVehicle class:
public abstract class EmergencyVehicle extends RoadVehicle {
public boolean codeBlue = false;
public EmergencyVehicle(String colour){
super(colour);
}
public boolean isEmergency () {
if (codeBlue == true) {
return true;
} else {
return false;
}
}
public void setEmergency(boolean newEmergency) {
codeBlue = newEmergency;
}
}
This is a homework exercise so I don't want the answer per se, but does the above code make sense?
For example, if I add a new EmergencyVehicle, I want an if statement depending on what colour the vehicle I add is.
1st Remark
Don't call
this("red");
in the default constructor, do
colour = "red";
unless the EmergencyVehicle(String colour) RoadVehicle(String colour) constructor is doing something else.
2nd Remark
Don't compare using
if (colour == "red")
use
if ("red".equals(colour))
3rd Remark
The method
public String toString()
is supposed to return a string representation of the instance. You implementation only returns red or no which is not very informative. Use something like
return("FireEngine(colour=" + colour + ")");
I need to write a Java enumeration LetterGrade that represents letter grades A through F, including plus and minus grades.
Now this is my enumeration code:
public enum Grade {
A(true),
A_PLUS(true),
A_MINUS(true),
B(true),
B_PLUS(true),
B_MINUS(true),
C(true),
D(true),
E(true),
F(false);
final private boolean passed;
private Grade(boolean passed) {
this.passed = passed;
}
public boolean isPassing() {
return this.passed;
}
#Override
public String toString() {
final String name = name();
if (name.contains("PLUS")) {
return name.charAt(0) + "+";
}
else if (name.contains("MINUS")) {
return name.charAt(0) + "-";
}
else {
return name;
}
}
What I am confused about is writing the main program. I think it could be quite straightforward but I have no clue on how to start it.
I don't want the whole code. Just a few lines to give me a head start. The rest I will try to figure out on my own.
I imagine you have a Student class that looks like this:
class Student {
protected Grade grade = null;
public Student(Grade g) {
this.grade = g;
}
}
Then you simply add a method in this class calling the isPassing method from your enum:
public boolean isPassing() {
if (this.grade != null)
return this.grade.isPassing();
return false;
}
This is supposing the passed boolean in Grade are correctly set and are invariant.
Hello i am writing a program that creates a method that can remove items from an arraylist and add them to another ArrayList (under certain conditions). This is the method I am supposed to create:
A method called giveAwayFish() which represents a person
returning his fish to the pond and/or giving them away to another fisher.
It will go through all of this person's fish ( the one giving the fish away) and see if the other fisher ( the one who will be receiving the fish) is willing to keep any. If the other fisher wants any, they are to be given to that fisher. If the fisher is unwilling to keep the fish, then these fish must be returned to the pond.
I tried writing out this method about a hundred times and I can not for the life of me figure out what to do. I was able to remove all the fish from the persons array but I do not know how to add them back. This is what I need help with.
Here is my code if it helps:
import java.util.*;
public class Fisher
{
private String name;
private Fish [] fishCaught;
private int numFishCaught;
private int keepSize;
public static int LIMIT = 10;
public String getName()
{
return this.name;
}
public int getNumFishCaught()
{
return this.numFishCaught;
}
public int getKeepSize()
{
return this.keepSize;
}
public Fisher(String n, int k)
{
name = n;
keepSize = k;
}
public String toString()
{
return(this.name + " with " + this.numFishCaught + " fish as follows:");
}
private ArrayList<Fish> fishesCaught = new ArrayList<Fish>();
public void keep(Fish fish)
{
if(this.numFishCaught < LIMIT)
{
fishesCaught.add(fish);
numFishCaught++;
}
}
public boolean likes(Fish fish)
{
if(fish.size >= this.keepSize && fish.species != "Sunfish")
{
return true;
}
else
{
return false;
}
}
public void listFish()
{
System.out.println(this.toString());
for(Fish fish : fishesCaught)
{
System.out.println(fish.toString());
}
}
public void goFishingIn(Pond pond)
{
Fish fish = pond.catchAFish();
if(likes(fish))
{
this.keep(fish);
}
else
{
pond.add(fish);
}
}
public void giveAwayFish(Fisher fisher, Pond pond)
{
Fish fish = fishesCaught;
if(fisher.likes(fish))
{
fishesCaught.clear();
this.numFishCaught = 0;
}
}
}
Biggest problem here is (yes, there are lots of other problems), in your giveAwayFish(), you wrote
Fish fish = fishesCaught;
However fishesCaught is a List<Fish>. That can't even compile.
I believe what you want to do is something like (in psuedo code):
for (Fish fish : fishesCaught) {
if (fisher.like(fish)) {
fisher.keep(fish);
} else {
pond.addFish(fish);
}
}
fishesCaught.clear();
This question already has answers here:
Using Comparable for multiple dynamic fields of VO in java
(7 answers)
Closed 8 years ago.
I have a List of Java objects that I want to sort according to more than one field.
public class graduationCeremony {
String campus;
String faculty;
String building;
}
Is it possible to use a Comparator or the Comparable interface to sort the list according to multiple fields? All the examples I have seen sort according to only one field. In other words, one can sort by 'campus' OR 'faculty' OR 'building'. I want to sort by 'campus', then 'faculty', then 'building' (as it exists in SQL: ORDER BY campus, faculty, building)
I think this question has been asked before, but I don't understand the accepted answer. Can someone expand or illustrate this answer?
Your Comparator would look like this:
public class GraduationCeremonyComparator implements Comparator<GraduationCeremony> {
public int compare(GraduationCeremony o1, GraduationCeremony o2) {
int value1 = o1.campus.compareTo(o2.campus);
if (value1 == 0) {
int value2 = o1.faculty.compareTo(o2.faculty);
if (value2 == 0) {
return o1.building.compareTo(o2.building);
} else {
return value2;
}
}
return value1;
}
}
Basically it continues comparing each successive attribute of your class whenever the compared attributes so far are equal (== 0).
Yes, you absolutely can do this. For example:
public class PersonComparator implements Comparator<Person>
{
public int compare(Person p1, Person p2)
{
// Assume no nulls, and simple ordinal comparisons
// First by campus - stop if this gives a result.
int campusResult = p1.getCampus().compareTo(p2.getCampus());
if (campusResult != 0)
{
return campusResult;
}
// Next by faculty
int facultyResult = p1.getFaculty().compareTo(p2.getFaculty());
if (facultyResult != 0)
{
return facultyResult;
}
// Finally by building
return p1.getBuilding().compareTo(p2.getBuilding());
}
}
Basically you're saying, "If I can tell which one comes first just by looking at the campus (before they come from different campuses, and the campus is the most important field) then I'll just return that result. Otherwise, I'll continue on to compare faculties. Again, stop if that's enough to tell them apart. Otherwise, (if the campus and faculty are the same for both people) just use the result of comparing them by building."
If you know in advance which fields to use to make the comparison, then other people gave right answers.
What you may be interested in is to sort your collection in case you don't know at compile-time which criteria to apply.
Imagine you have a program dealing with cities:
protected Set<City> cities;
(...)
Field temperatureField = City.class.getDeclaredField("temperature");
Field numberOfInhabitantsField = City.class.getDeclaredField("numberOfInhabitants");
Field rainfallField = City.class.getDeclaredField("rainfall");
program.showCitiesSortBy(temperatureField, numberOfInhabitantsField, rainfallField);
(...)
public void showCitiesSortBy(Field... fields) {
List<City> sortedCities = new ArrayList<City>(cities);
Collections.sort(sortedCities, new City.CityMultiComparator(fields));
for (City city : sortedCities) {
System.out.println(city.toString());
}
}
where you can replace hard-coded field names by field names deduced from a user request in your program.
In this example, City.CityMultiComparator<City> is a static nested class of class City implementing Comparator:
public static class CityMultiComparator implements Comparator<City> {
protected List<Field> fields;
public CityMultiComparator(Field... orderedFields) {
fields = new ArrayList<Field>();
for (Field field : orderedFields) {
fields.add(field);
}
}
#Override
public int compare(City cityA, City cityB) {
Integer score = 0;
Boolean continueComparison = true;
Iterator itFields = fields.iterator();
while (itFields.hasNext() && continueComparison) {
Field field = itFields.next();
Integer currentScore = 0;
if (field.getName().equalsIgnoreCase("temperature")) {
currentScore = cityA.getTemperature().compareTo(cityB.getTemperature());
} else if (field.getName().equalsIgnoreCase("numberOfInhabitants")) {
currentScore = cityA.getNumberOfInhabitants().compareTo(cityB.getNumberOfInhabitants());
} else if (field.getName().equalsIgnoreCase("rainfall")) {
currentScore = cityA.getRainfall().compareTo(cityB.getRainfall());
}
if (currentScore != 0) {
continueComparison = false;
}
score = currentScore;
}
return score;
}
}
You may want to add an extra layer of precision, to specify, for each field, whether sorting should be ascendant or descendant. I guess a solution is to replace Field objects by objects of a class you could call SortedField, containing a Field object, plus another field meaning ascendant or descendant.
Hope this Helps:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
class Person implements Comparable {
String firstName, lastName;
public Person(String f, String l) {
this.firstName = f;
this.lastName = l;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String toString() {
return "[ firstname=" + firstName + ",lastname=" + lastName + "]";
}
public int compareTo(Object obj) {
Person emp = (Person) obj;
int deptComp = firstName.compareTo(emp.getFirstName());
return ((deptComp == 0) ? lastName.compareTo(emp.getLastName()) : deptComp);
}
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person emp = (Person) obj;
return firstName.equals(emp.getFirstName()) && lastName.equals(emp.getLastName());
}
}
class PersonComparator implements Comparator<Person> {
public int compare(Person emp1, Person emp2) {
int nameComp = emp1.getLastName().compareTo(emp2.getLastName());
return ((nameComp == 0) ? emp1.getFirstName().compareTo(emp2.getFirstName()) : nameComp);
}
}
public class Main {
public static void main(String args[]) {
ArrayList<Person> names = new ArrayList<Person>();
names.add(new Person("E", "T"));
names.add(new Person("A", "G"));
names.add(new Person("B", "H"));
names.add(new Person("C", "J"));
Iterator iter1 = names.iterator();
while (iter1.hasNext()) {
System.out.println(iter1.next());
}
Collections.sort(names, new PersonComparator());
Iterator iter2 = names.iterator();
while (iter2.hasNext()) {
System.out.println(iter2.next());
}
}
}
You just need to have your class inherit from Comparable.
then implement the compareTo method the way you like.
You have to write your own compareTo() method that has the Java code needed to perform the comparison.
If we wanted for example to compare two public fields, campus, then faculty, we might do something like:
int compareTo(GraduationCeremony gc)
{
int c = this.campus.compareTo(gc.campus);
if( c != 0 )
{
//sort by campus if we can
return c;
}
else
{
//campus equal, so sort by faculty
return this.faculty.compareTo(gc.faculty);
}
}
This is simplified but hopefully gives you an idea. Consult the Comparable and Comparator docs for more info.