diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java index 579ef424a3f31..a1b8d98b2a271 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java @@ -16,6 +16,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.ServiceLoader; import java.util.Set; @@ -26,7 +27,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -116,7 +116,7 @@ public ArcContainerImpl(CurrentContextFactory currentContextFactory, boolean str id = String.valueOf(ID_GENERATOR.incrementAndGet()); running = new AtomicBoolean(true); List> beans = new ArrayList<>(); - Map>> beansByRawType = new HashMap<>(); + Map>> beansByRawType = new HashMap<>(); List>> removedBeans = new ArrayList<>(); List> interceptors = new ArrayList<>(); List> decorators = new ArrayList<>(); @@ -179,16 +179,8 @@ public ArcContainerImpl(CurrentContextFactory currentContextFactory, boolean str instance = InstanceImpl.forGlobalEntrypoint(Object.class, Collections.emptySet()); this.beans = List.copyOf(beans); - this.beansByRawType = Map.copyOf(beansByRawType); - // Trim the size of the non-singleton lists - this.beansByRawType.forEach(new BiConsumer>>() { - @Override - public void accept(String key, List> val) { - if (val.size() > 1) { - ((ArrayList>) val).trimToSize(); - } - } - }); + this.beansByRawType = beansByRawType.entrySet().stream() + .collect(Collectors.toUnmodifiableMap(Entry::getKey, e -> List.copyOf(e.getValue()))); this.interceptors = List.copyOf(interceptors); this.decorators = List.copyOf(decorators); @@ -245,7 +237,7 @@ public List get() { this.contexts = contextsBuilder.build(); } - static void precomputeBeanRawTypes(Map>> map, InjectableBean bean) { + static void precomputeBeanRawTypes(Map>> map, InjectableBean bean) { for (Type type : bean.getTypes()) { if (Object.class.equals(type)) { continue; @@ -256,18 +248,19 @@ static void precomputeBeanRawTypes(Map>> map, Inj } rawType = Types.boxedClass(rawType); String key = rawType.getName(); - List> match = map.get(key); + Set> match = map.get(key); if (match == null) { // very often a singleton list will be used - map.put(key, List.of(bean)); + map.put(key, Set.of(bean)); } else { - // we don't expect large lists so this should be fine performance wise if (match.contains(bean)) { continue; } if (match.size() == 1) { - List> newMatch = new ArrayList<>(); - newMatch.add(match.get(0)); + // a set of 2 elements is also a relatively common case + map.put(key, Set.of(match.iterator().next(), bean)); + } else if (match.size() == 2) { + Set> newMatch = new HashSet<>(match); newMatch.add(bean); map.put(key, newMatch); } else { @@ -536,7 +529,7 @@ private Notifier notifierOrNull(Set qualifiers) { return notifier.isEmpty() ? null : notifier; } - private static void addBuiltInBeans(List> beans, Map>> beansByRawType) { + private static void addBuiltInBeans(List> beans, Map>> beansByRawType) { // BeanManager, Event, Instance, InjectionPoint BeanManagerBean beanManagerBean = new BeanManagerBean(); beans.add(beanManagerBean);