How to wrap a matrix blocktype occurrence loop inside a ul?
A possible solution could be this:
Instead of outputting your blockType3 immediately, save all blockType3 ID's in an array. When your loop has finished (check for loop.last) output all the blocktypes from the array at once.

This code is just as an example (untested):

{% set arrBlockType3 = [] %}
{% for block in entry.matrixField.all() %}
    {% switch block.type %}
        {% case 'blockType1' %}
            &lt;div&gt;
                {{ block.field }}
            &lt;/div&gt;
            {% case 'blockType2' %}
            &lt;div&gt;
                {{ block.field }}
            &lt;/div&gt;
            {% case 'blockType3' %}
                {% set arrBlockType3 = arrBlockType3 | merge([block.id]) %}
    {% endswitch %}
    {% if loop.last %}
        &lt;ul&gt;
        {% for id in arrBlockType3 %}
            {% set block = entry.matrixField.id(id).first() %}
            &lt;li&gt;{{ block.field }}&lt;/li&gt;
        {% endfor %}
        &lt;/ul&gt;
    {% endif %}
{% endfor %}