001package org.biopax.paxtools.util; 002 003import org.biopax.paxtools.model.BioPAXElement; 004 005import java.util.HashSet; 006import java.util.List; 007import java.util.Set; 008 009/** 010 * This class performs set operations based on equivalence. 011 */ 012public class SetEquivalenceChecker 013{ 014 /** 015 * @param set1 First set to be checked. 016 * @param set2 Second set to be checked 017 * @param <T> Both sets should be of type that extends from T. 018 * @return true iff both sets are of equal size and all objects in set1 has an equivalent object in set2. 019 */ 020 public static <T extends BioPAXElement> boolean isEquivalent(Set<? extends T> set1, Set<? extends T> set2) 021 { 022 if (set1 != null && !set1.isEmpty() && set2 != null && !set2.isEmpty()) 023 { 024 int size = set1.size(); 025 if (size == set2.size()) 026 { 027 EquivalenceGrouper<T> grouper = new EquivalenceGrouper<T>(); 028 grouper.addAll(set1); 029 if (grouper.getBuckets().size() == size) 030 { 031 grouper.addAll(set2); 032 return (grouper.getBuckets().size() == size); 033 } 034 } 035 } 036 037 //now, only if both null or both empty - return true 038 if( set1 == null && set2 == null //both null 039 || // or both not null but empty 040 set1 != null && set1.isEmpty() && set2 != null && set2.isEmpty()) 041 { 042 return true; 043 } 044 045 return false; 046 } 047 048 /** 049 * @param set Set to test if it contains an element equivalent to query 050 * @param query BPE to look for equivalents in set 051 * @return true iff there is an element of set that is equivalent to query. 052 */ 053 public static boolean containsEquivalent(Set<? extends BioPAXElement> set, BioPAXElement query) 054 { 055 if (set != null && query != null) 056 { 057 for (BioPAXElement element2 : set) 058 { 059 if (query.isEquivalent(element2)) 060 { 061 return true; 062 } 063 } 064 } 065 return false; 066 } 067 068 /** 069 * @param set1 First set to be checked. 070 * @param set2 Second set to be checked 071 * @param <T> Both sets should be of type that extends from T. 072 * @return elements of set1 that has an equivalent element in set2 073 */ 074 public static <T extends BioPAXElement> Set<T> findEquivalentIntersection(Set<? extends T> set1, 075 Set<? extends T> set2) 076 { 077 078 Set<T> value = new HashSet<T>(); 079 080 if (set1 != null && !set1.isEmpty() && set2 != null && !set2.isEmpty()) 081 { 082 EquivalenceGrouper<T> grouper = new EquivalenceGrouper<T>(); 083 grouper.addAll(set1); 084 if (grouper.getBuckets().size() < set1.size()) 085 { 086 throw new IllegalArgumentException("There should not be equivalent elements in a set"); 087 } 088 grouper.addAll(set2); 089 for (List<T> ts : grouper.getBuckets()) 090 { 091 if (ts.size() > 1) 092 { 093 for (T t : ts) 094 { 095 if (set1.contains(t)) 096 { 097 value.add(t); 098 } 099 } 100 } 101 } 102 } 103 return value; 104 } 105 106 /** 107 * @param set1 First set to be checked. 108 * @param set2 Second set to be checked 109 * @param <T> Both sets should be of type that extends from T. 110 * @return true iff there are at least one equivalent element between set1 and set2. 111 */ 112 public static <T extends BioPAXElement> boolean hasEquivalentIntersection(Set<? extends T> set1, 113 Set<? extends T> set2) 114 { 115 116 if (set1 != null && !set1.isEmpty() && set2 != null && !set2.isEmpty()) 117 { 118 EquivalenceGrouper<T> grouper = new EquivalenceGrouper<T>(); 119 grouper.addAll(set1); 120 if (grouper.getBuckets().size() == set1.size()) 121 { 122 grouper.addAll(set2); 123 return (grouper.getBuckets().size() < set1.size() + set2.size()); 124 } else 125 { 126 throw new IllegalArgumentException("There should not be equivalent elements in a set"); 127 } 128 } 129 return true; 130 } 131 132}