find matches between attributes from two different Objects
First off, a bug (or probably just a copy/paste error): countMatches is comparing age instead of eye color.
Then, any reason you are limited to Java 8? At the very least you should be using the LTS release 11, or better the current release 15.
Also, you have some minor formatting issues that don't confirm with standard Java conventions. Mostly it's wrong spacing: there should be spaces before { and between keywords (e.g. if) and (, but no spaces between method names and (.
Lombok
The annotations on the data classes could be most likely simplified to @Data @AllArgsConstructor. And you should even consider using @Value instead for immutable objects when ever possible, which can help avoiding bugs.
Spring DI
Generally autowiring private properties has been discouraged. You should prefer constructor injection. With Lombok's @RequiredArgsConstructor it becomes quite easy:
@Service
RequiredArgsConstructor
public class UserServiceImpl implements UserService{
    
    private final UserRepository userRepository;
    
    private final UserFilters userFilters;

    //....
}

Since you are injecting UserFilters it shouldn't be static i.e. @UtilityClass.
For a matter of fact I don't see why UserFilters is a separate class at all. Those methods don't look like they should be used outside of UserService, so they should belong as (private) methods in UserService.
Method UserServiceImpl.getMostMatchingUserId
The name isn't quite right and doesn't give enough information in my opinion. It's not a &quot;getter&quot;, so it should be called find... and nt get..., the meaning &quot;Most matching&quot; needs to be defined in a comment and the word &quot;youngest&quot; needs to be added.
Also it seems quite limiting to have the method return just the user ID.
One problem in here is the use of orElse on the result of min(). min() only returns an empty Optional, if the stream is empty, so in that case .get(0) will throw an exception.
A final though here, is that normally one would expect that the repository (or usually the database behind it) should filter the list of results. If the database would do the filtering, then this would scale better with more users.
Method UserFilters.getMostMatchingUserList
Also not a &quot;getter&quot;. filter... would be the most appropriate prefix here.
One could consider using a stream here, however in this specific case I don't think it would make the task much simpler/better to read. The only change I'd make here would be choose some better variable names: newUserList should be called filteredUserList and matchesInitialCount should be currentMatchesCount.
Method UserFilters.countMatches
This implementation is fine. Personally I'd leave it like this, and just add/change more property checks when needed, unless the list of properties needs to changed quickly or easily, for example, via configuration. It that case you need to work with reflection to find the properties.