How to extract only one allowed element from a stream?

Your current solution is good. You can try this way also to avoid collecting.

Use distinct() then count()

if (fields.stream().map(f -> f.getField()).distinct().count() != 1) 
      throw new IllegalArgumentException("could not match one exact element");

To get the value

String distrinctVal = fields.get(0).getField();

That would be the reduce solution.

Optional<String> distinctVal = fields.stream()
    .map(f -> f.getField())
    .reduce((a, b) -> {
        if(a != b) throw new IllegalArgumentException("could not match one exact element");
        return a;
    });

Well you could certainly do this in several ways but as to which is more elegant can vary from person to person.

Anyway if you were to attempt this via streams this is how i would have done it:

With a slight modification to my answer here you could do:

boolean result = fields.stream()
                       .map(f -> f.getField())
                       .distinct()
                       .limit(2) // ENABLE SHORT CIRCUITING
                       .count() != 1;

if (result) throw new IllegalArgumentException("could not match one exact element");

String distinctVal = fields.get(0).getField();

The benefit of this approach is basically utilising limit(2) to enable optimisation where possible.

Conclusion : your current approach is quite good actually so I wouldn't be surprised if you were to stick to that but you also have the choice of this approach where you can short-circuit the pipeline.