001/* 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.util; 021 022import jakarta.annotation.Nonnull; 023import jakarta.annotation.Nullable; 024import org.apache.commons.collections4.CollectionUtils; 025 026import java.util.Collection; 027import java.util.Collections; 028import java.util.HashSet; 029import java.util.Set; 030 031import static java.util.Collections.unmodifiableCollection; 032 033public class CollectionUtil { 034 035 /** 036 * Non instantiable 037 */ 038 private CollectionUtil() { 039 // nothing 040 } 041 042 /** 043 * Returns an immutable union of both collections. If either or both arguments are 044 * <code>null</code> they will be treated as an empty collection, meaning 045 * that even if both arguments are <code>null</code>, an empty immutable 046 * collection will be returned. 047 * <p> 048 * DO NOT use this method if the underlying collections can be changed 049 * after calling this method, as the behaviour is indeterminate. 050 * </p> 051 * 052 * @param theCollection0 The first set in the union, or <code>null</code>. 053 * @param theCollection1 The second set in the union, or <code>null</code>. 054 * @return Returns a union of both collections. Will not return <code>null</code> ever. 055 * @since 7.4.0 056 */ 057 @Nonnull 058 public static <T> Collection<T> nullSafeUnion( 059 @Nullable Collection<T> theCollection0, @Nullable Collection<T> theCollection1) { 060 Collection<T> collection0 = theCollection0; 061 if (collection0 != null && collection0.isEmpty()) { 062 collection0 = null; 063 } 064 Collection<T> collection1 = theCollection1; 065 if (collection1 != null && collection1.isEmpty()) { 066 collection1 = null; 067 } 068 if (collection0 == null && collection1 == null) { 069 return Collections.emptySet(); 070 } 071 if (collection0 == null) { 072 return unmodifiableCollection(collection1); 073 } 074 if (collection1 == null) { 075 return unmodifiableCollection(collection0); 076 } 077 return CollectionUtils.union(collection0, collection1); 078 } 079 080 /** 081 * This method is equivalent to <code>Set.of(...)</code> but is kept here 082 * and used instead of that method because Set.of is not present on Android 083 * SDKs (at least up to 29). 084 * <p> 085 * Sets returned by this method are unmodifiable. 086 * </p> 087 */ 088 @SuppressWarnings("unchecked") 089 public static <T> Set<T> newSet(T... theValues) { 090 HashSet<T> retVal = new HashSet<>(); 091 Collections.addAll(retVal, theValues); 092 return Collections.unmodifiableSet(retVal); 093 } 094}