Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Introduction to Functional Programming Reduction and Aggregation Reduce Housing Records

Jenna Dercole
Jenna Dercole
30,224 Points

"Incompatible types: inferred type does not conform to upper bound(s)"?

Hello,

I've written the two declarative methods based on the examples in the "Reduction Operations" video, but the second one asking to return the max using a Comparator is giving me some trouble.

Specifically, it's throwing the following error on the line where I call the Comparator.comparingInt method: "incompatible types: inferred type does not conform to upper bound(s) inferred: Integer upper bound(s): HousingRecord,Object"

I suppose it's also worth mentioning that I receive a warning when I populate the comparingInt parameter with what I currently have, saying: "Non-static method cannot be referenced from a static context." I have a feeling that I'm using the method reference incorrectly. Maybe I should be using an Integer generic somehow?

Have a look at my code below:

package com.teamtreehouse.challenges.homes;

import com.teamtreehouse.challenges.homes.model.HousingRecord;
import com.teamtreehouse.challenges.homes.service.HousingRecordService;

import java.util.Comparator;
import java.util.List;
import java.util.OptionalInt;

public class Main {
  public static void main(String[] args) {
    HousingRecordService service = new HousingRecordService();
    List<HousingRecord> records = service.getAllHousingRecords();
    System.out.printf("There are %d housing records. %n %n", records.size());

    System.out.println("Lowest home value index:");
    int lowest = getLowestHomeValueIndexImperatively(records);
    System.out.println("Imperatively:  " + lowest);
    OptionalInt lowestDeclaratively = getLowestHomeValueIndexDeclaratively(records);
    System.out.println("Declaratively:  " + lowestDeclaratively);

    System.out.printf("%n%nHighest housing record based on current value index:%n");
    HousingRecord record = getHighestValueIndexHousingRecordImperatively(records);
    System.out.println("Imperatively:  " + record);
    OptionalInt recordDeclaratively = getHighestValueIndexHousingRecordDeclaratively(records);
    System.out.println("Declaratively:  " + recordDeclaratively);
  }

  public static int getLowestHomeValueIndexImperatively(List<HousingRecord> records) {
    int lowest = -1;
    for (HousingRecord record : records) {
      int index = record.getCurrentHomeValueIndex();
      if (lowest == -1) {
        lowest = index;
      } else {
        if (index < lowest) {
          lowest = index;
        }
      }
    }
    return lowest;
  }

  public static OptionalInt getLowestHomeValueIndexDeclaratively(List<HousingRecord> records) {
    // TODO: Create a stream off the records
    return records.stream()
    // TODO: Map the stream to an IntStream on `HousingRecord.getCurrentHomeValueIndex` to expose new methods
    .mapToInt(HousingRecord::getCurrentHomeValueIndex)
      .min();
    // TODO: Return the minimum value from the stream.  It should be an optional because records could be empty.

  }

  public static HousingRecord getHighestValueIndexHousingRecordImperatively(List<HousingRecord> records) {
    HousingRecord maxRecord = null;
    for (HousingRecord record : records) {
      if (maxRecord == null) {
        maxRecord = record;
      } else {
        if (record.getCurrentHomeValueIndex() > maxRecord.getCurrentHomeValueIndex()) {
          maxRecord = record;
        }
      }
    }
    return maxRecord;
  }

  public static OptionalInt getHighestValueIndexHousingRecordDeclaratively(List<HousingRecord> records) {
    // TODO: Create a stream off of the records
    return records.stream()
    // TODO: Find and return the maximum using a Comparator that compares the current home value index
      .map(HousingRecord::getCurrentHomeValueIndex)
      .max(Comparator.comparingInt(HousingRecord::getCurrentHomeValueIndex));
  }
}

Any guidance would be appreciated. Thanks!

2 Answers

Mohammad Laif
PLUS
Mohammad Laif
Courses Plus Student 22,297 Points

I faced same problems, and I get disturbed for an hour ?.

First, you need to clear the change you made to getHighestValueIndexHousingRecordDeclaratively() which was returning "Optional<HousingRecord>". (my intelliJ IDEA change it too, when I used quit fix and that raised "incompatible types: inferred type does not conform to upper bound(s) inferred: Integer upper bound(s)"). Just unzip the file and start again.

Second, about "Non-static method cannot be referenced from a static context", you don't need to map the stream, so just delete the line:

      .map(HousingRecord::getCurrentHomeValueIndex)

and leave

      .max(Comparator.comparingInt(HousingRecord::getCurrentHomeValueIndex));

I don't know why it raise that error message! But I think mapping the HousingRecord::getCurrentHomeValueIndex in that deleted line, makes the stream Integer rather than HousingRecord stream. But in this task we need to compare the properties of HousingRecocrd object by calling its getCurrentHomeValueIndex() getter, and that Integer stream doesn't have getCurrentHomeValueIndex(). So that crazy error raised up!

Complete code

package com.teamtreehouse.challenges.homes;

import com.teamtreehouse.challenges.homes.model.HousingRecord;
import com.teamtreehouse.challenges.homes.service.HousingRecordService;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Main {
  public static void main(String[] args) {
    HousingRecordService service = new HousingRecordService();
    List<HousingRecord> records = service.getAllHousingRecords();
    System.out.printf("There are %d housing records. %n %n", records.size());

    System.out.println("Lowest home value index:");
    int lowest = getLowestHomeValueIndexImperatively(records);
    System.out.println("Imperatively:  " + lowest);
    OptionalInt lowestDeclaratively = getLowestHomeValueIndexDeclaratively(records);
    System.out.println("Declaratively:  " + lowestDeclaratively);

    System.out.printf("%n%nHighest housing record based on current value index:%n");
    HousingRecord record = getHighestValueIndexHousingRecordImperatively(records);
    System.out.println("Imperatively:  " + record);
    Optional<HousingRecord> recordDeclaratively = getHighestValueIndexHousingRecordDeclaratively(records);
    System.out.println("Declaratively:  " + recordDeclaratively);
  }

  public static int getLowestHomeValueIndexImperatively(List<HousingRecord> records) {
    int lowest = -1;
    for (HousingRecord record : records) {
      int index = record.getCurrentHomeValueIndex();
      if (lowest == -1) {
        lowest = index;
      } else {
        if (index < lowest) {
          lowest = index;
        }
      }
    }
    return lowest;
  }

  public static OptionalInt getLowestHomeValueIndexDeclaratively(List<HousingRecord> records) {
    // TODO: Create a stream off the records
    return records.stream()
      // TODO: Map the stream to an IntStream on `HousingRecord.getCurrentHomeValueIndex` to expose new methods
      .mapToInt(HousingRecord::getCurrentHomeValueIndex)
      // TODO: Return the minimum value from the stream.  It should be an optional because records could be empty.
      .min();
    //return OptionalInt.empty();
  }

  public static HousingRecord getHighestValueIndexHousingRecordImperatively(List<HousingRecord> records) {
    HousingRecord maxRecord = null;
    for (HousingRecord record : records) {
      if (maxRecord == null) {
        maxRecord = record;
      } else {
        if (record.getCurrentHomeValueIndex() > maxRecord.getCurrentHomeValueIndex()) {
          maxRecord = record;
        }
      }
    }
    return maxRecord;
  }

  public static Optional<HousingRecord> getHighestValueIndexHousingRecordDeclaratively(List<HousingRecord> records) {
    // TODO: Create a stream off of the records
    return records.stream()
    // TODO: Find and return the maximum using a Comparator that compares the current home value index
      .max(Comparator.comparingInt(HousingRecord::getCurrentHomeValueIndex));
  }


}

It's been two years since this has been posted, but man! I've been stuck on this code all day yesterday and I stumble upon this helpful comment. Thanks so much for giving such a detailed answer! Kudos to you my friend.

I think we all focused a lot Craigs video by writing exactly 😅 .map(House..) .max(Comparator..Integer::Int) and thought that will work the same in his challenge, which is not.

I think we didn't read clearly his TODO it didn't say Call steam then map.. instead he wrote: Create a stream off of the records. Find and return the maximum using a Comparator that compares the current home value index

which mean

  1. steam()
  2. max()
  3. Comparator comparingInt
  4. HouseRecord
  5. Integer::intValue

anyway, Mohammad, you are a hero! Saving our time! :) Good Job! 🏆 😅

Jenna Dercole
Jenna Dercole
30,224 Points

This worked--thanks a million! :)