001/* 002 * Copyright (C) 2009 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.collect.testing; 018 019import static java.util.Arrays.asList; 020 021import com.google.common.annotations.GwtCompatible; 022import java.util.ArrayList; 023import java.util.Collection; 024import java.util.List; 025import java.util.Set; 026import org.jspecify.annotations.NonNull; 027import org.jspecify.annotations.NullMarked; 028import org.jspecify.annotations.Nullable; 029 030/** 031 * A simplistic set which implements the bare minimum so that it can be used in tests without 032 * relying on any specific Set implementations. Slow. Explicitly allows null elements so that they 033 * can be used in the testers. 034 * 035 * @author Regina O'Dell 036 */ 037@GwtCompatible 038@NullMarked 039public final class MinimalSet<E extends @Nullable Object> extends MinimalCollection<E> 040 implements Set<E> { 041 042 @SuppressWarnings("unchecked") // empty Object[] as E[] 043 public static <E extends @Nullable Object> MinimalSet<E> of(E... contents) { 044 return ofClassAndContents(Object.class, (E[]) new Object[0], asList(contents)); 045 } 046 047 @SuppressWarnings("unchecked") // empty Object[] as E[] 048 public static <E extends @Nullable Object> MinimalSet<E> from(Collection<? extends E> contents) { 049 return ofClassAndContents(Object.class, (E[]) new Object[0], contents); 050 } 051 052 public static <E extends @Nullable Object> MinimalSet<E> ofClassAndContents( 053 Class<? super @NonNull E> type, E[] emptyArrayForContents, Iterable<? extends E> contents) { 054 List<E> setContents = new ArrayList<>(); 055 for (E e : contents) { 056 if (!setContents.contains(e)) { 057 setContents.add(e); 058 } 059 } 060 return new MinimalSet<>(type, setContents.toArray(emptyArrayForContents)); 061 } 062 063 private MinimalSet(Class<? super @NonNull E> type, E... contents) { 064 super(type, true, contents); 065 } 066 067 /* 068 * equals() and hashCode() are more specific in the Set contract. 069 */ 070 071 @Override 072 public boolean equals(@Nullable Object object) { 073 if (object instanceof Set) { 074 Set<?> that = (Set<?>) object; 075 return (this.size() == that.size()) && this.containsAll(that); 076 } 077 return false; 078 } 079 080 @Override 081 public int hashCode() { 082 int hashCodeSum = 0; 083 for (Object o : this) { 084 hashCodeSum += (o == null) ? 0 : o.hashCode(); 085 } 086 return hashCodeSum; 087 } 088}