両端のついたちに意味はない

STARTENDは年月を指定するためにあるので、
day of monthがついたちであることに特に意味はない。
そこで、LocalDateでなくYearMonthの方が意図を読みやすくなるかもしれない。

import static java.time.DayOfWeek.SUNDAY;
import java.time.YearMonth;
import static java.time.temporal.ChronoUnit.MONTHS;
import static java.time.temporal.TemporalAdjusters.dayOfWeekInMonth;
import java.util.stream.Stream;

public class ThirdSundays {
    public static void main(String[] args) {
        final YearMonth START = YearMonth.of(2016, 1);
        final YearMonth END = YearMonth.of(2017, 1);
        Stream
            .iterate(START, d -> d.plusMonths(1))
            .limit(MONTHS.between(START, END))
            .forEach(
                d -> System.out.println(
                    d.atDay(1).with(dayOfWeekInMonth(3, SUNDAY))
                )
            );
    }
}

LocalDateYearMonthに置き換わっただけである。
ただし、

                    d.with(dayOfWeekInMonth(3, SUNDAY))

のままではdayOfWeekInMonthで得られるTemporalAdjusterYearMonthを調整できない。
day of monthは何でもいいので手っ取り早くLocalDateYearMonthにするためにYearMonth#atDayを使っている。