@@ -42,6 +42,7 @@ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISI
4242import edu .rice .cs .plt .tuple .Pair ;
4343import edu .rice .cs .plt .iter .SizedIterable ;
4444import edu .rice .cs .plt .iter .IterUtil ;
45+ import edu .rice .cs .plt .object .ObjectUtil ;
4546
4647public final class CollectUtil {
4748
@@ -313,23 +314,31 @@ public static <T> PredicateSet<T> makeSet(Option<? extends T> opt) {
313314 * Create an immutable {@code Relation} based on the given elements. May depend on a valid
314315 * {@code hashCode()} implementation.
315316 */
316- public static <T1 , T2 > Relation <T1 , T2 > makeRelation (Iterable <? extends Pair <T1 , T2 >> pairs ) {
317+ public static <T1 , T2 > Relation <T1 , T2 > makeRelation (Iterable <? extends Pair <? extends T1 , ? extends T2 >> pairs ) {
317318 if (IterUtil .isEmpty (pairs )) {
318319 return EmptyRelation .make ();
319320 }
320321 else if (IterUtil .sizeOf (pairs , 2 ) == 1 ) {
321- return new SingletonRelation <T1 , T2 >(IterUtil .first (pairs ));
322+ Pair <? extends T1 , ? extends T2 > elt = IterUtil .first (pairs );
323+ return new SingletonRelation <T1 , T2 >(elt .first (), elt .second ());
322324 }
323325 else {
324326 Relation <T1 , T2 > result = IndexedRelation .makeHashBased ();
325- result .addAll (asCollection (pairs ));
327+ for (Pair <? extends T1 , ? extends T2 > elt : pairs ) {
328+ result .add (elt .first (), elt .second ());
329+ }
326330 return new ImmutableRelation <T1 , T2 >(result ) {
327331 @ Override public boolean hasFixedSize () { return true ; }
328332 @ Override public boolean isStatic () { return true ; }
329333 };
330334 }
331335 }
332336
337+ /** Make an {@code ArrayList} with the given elements. */
338+ public static <T > List <T > makeList (Iterable <? extends T > iter ) {
339+ return makeArrayList (iter );
340+ }
341+
333342 /** Make an {@code ArrayList} with the given elements. */
334343 public static <T > ArrayList <T > makeArrayList (Iterable <? extends T > iter ) {
335344 if (iter instanceof Collection <?>) {
@@ -484,11 +493,63 @@ public static <T1, T2> ImmutableRelation<T1, T2> immutable(Relation<T1, T2> r) {
484493 return new ImmutableRelation <T1 , T2 >(r );
485494 }
486495
496+ /** Alias for {@link #makeSet}. */
497+ public static <T > PredicateSet <T > snapshot (Set <? extends T > set ) {
498+ return makeSet (set );
499+ }
500+
501+ /**
502+ * Produce a snapshot of {@code set} if its composite size is greater than the given threshold.
503+ * @see ObjectUtil#compositeSize
504+ */
505+ public static <T > Iterable <T > conditionalSnapshot (Set <T > set , int threshold ) {
506+ if (ObjectUtil .compositeSize (set ) > threshold ) { return makeSet (set ); }
507+ else { return set ; }
508+ }
509+
510+ /** Alias for {@link #makeRelation}. */
511+ public static <T1 , T2 > Relation <T1 , T2 > snapshot (Relation <? extends T1 , ? extends T2 > relation ) {
512+ return makeRelation (relation );
513+ }
514+
515+ /**
516+ * Produce a snapshot of {@code set} if its composite size is greater than the given threshold.
517+ * @see ObjectUtil#compositeSize
518+ */
519+ public static <T1 , T2 > Relation <T1 , T2 > conditionalSnapshot (Relation <T1 , T2 > rel , int threshold ) {
520+ if (ObjectUtil .compositeSize (rel ) > threshold ) { return makeRelation (rel ); }
521+ else { return rel ; }
522+ }
523+
524+ /** Invoke the {@code HashMap#HashMap(Map)} constructor. */
525+ public static <K , V > LambdaMap <K , V > snapshot (Map <? extends K , ? extends V > map ) {
526+ return new DelegatingMap <K , V >(new HashMap <K , V >(map ));
527+ }
528+
529+ /**
530+ * Produce a snapshot of {@code set} if its composite size is greater than the given threshold.
531+ * @see ObjectUtil#compositeSize
532+ */
533+ public static <K , V > Map <K , V > conditionalSnapshot (Map <K , V > map , int threshold ) {
534+ if (ObjectUtil .compositeSize (map ) > threshold ) { return snapshot (map ); }
535+ else { return map ; }
536+ }
537+
538+ /** Alias for {@link #makeArrayList}. */
539+ public static <T > List <T > snapshot (List <? extends T > list ) {
540+ return makeArrayList (list );
541+ }
542+
487543 /** Produce a lazy union of two sets. Size-related operations have poor performance. */
488544 public static <T > PredicateSet <T > union (Set <? extends T > s1 , Set <? extends T > s2 ) {
489545 return new UnionSet <T >(s1 , s2 );
490546 }
491547
548+ /** Produce a lazy union of a set with an additional singleton element. */
549+ public static <T > PredicateSet <T > union (Set <? extends T > set , T elt ) {
550+ return new UnionSet <T >(set , new SingletonSet <T >(elt ));
551+ }
552+
492553 /** Produce a lazy intersection of two sets. Size-related operations have poor performance. */
493554 public static <T > PredicateSet <T > intersection (Set <?> s1 , Set <? extends T > s2 ) {
494555 return new IntersectionSet <T >(s1 , s2 );
@@ -502,6 +563,14 @@ public static <T> PredicateSet<T> complement(Set<? extends T> domain, Set<?> exc
502563 return new ComplementSet <T >(domain , excluded );
503564 }
504565
566+ /**
567+ * Produce the complement of a singleton in a domain set, or, equivalently, a set with
568+ * a certain element removed.
569+ */
570+ public static <T > PredicateSet <T > complement (Set <? extends T > domain , T excluded ) {
571+ return new ComplementSet <T >(domain , new SingletonSet <T >(excluded ));
572+ }
573+
505574 /** Lazily filter the given set. Size-related operations have poor performance. */
506575 public static <T > PredicateSet <T > filter (Set <? extends T > set , Predicate <? super T > predicate ) {
507576 return new FilteredSet <T >(set , predicate );
@@ -512,6 +581,38 @@ public static <T1, T2> Relation<T1, T2> cross(Set<? extends T1> left, Set<? exte
512581 return new CartesianRelation <T1 , T2 >(left , right );
513582 }
514583
584+ /** Produce a lazy union of two relations. Size-related operations have poor performance. */
585+ public static <T1 , T2 > Relation <T1 , T2 > union (Relation <T1 , T2 > r1 , Relation <T1 , T2 > r2 ) {
586+ return new UnionRelation <T1 , T2 >(r1 , r2 );
587+ }
588+
589+ /** Produce a lazy union of a relation with an additional singleton entry. */
590+ public static <T1 , T2 > Relation <T1 , T2 > union (Relation <T1 , T2 > rel , T1 first , T2 second ) {
591+ return new UnionRelation <T1 , T2 >(rel , new SingletonRelation <T1 , T2 >(first , second ));
592+ }
593+
594+ /** Produce a lazy intersection of two relations. Size-related operations have poor performance. */
595+ public static <T1 , T2 > Relation <T1 , T2 > intersection (Relation <T1 , T2 > r1 , Relation <T1 , T2 > r2 ) {
596+ return new IntersectionRelation <T1 , T2 >(r1 , r2 );
597+ }
598+
599+ /**
600+ * Produce the complement of a relation in a domain, or, equivalently, the difference of two
601+ * relations. Size-related operations have poor performance.
602+ */
603+ public static <T1 , T2 > Relation <T1 , T2 > complement (Relation <T1 , T2 > domain ,
604+ Relation <? super T1 , ? super T2 > excluded ) {
605+ return new ComplementRelation <T1 , T2 >(domain , excluded );
606+ }
607+
608+ /**
609+ * Produce the complement of a singleton in a domain relation, or, equivalently, a relation with
610+ * a certain entry removed.
611+ */
612+ public static <T1 , T2 > Relation <T1 , T2 > complement (Relation <T1 , T2 > domain , T1 first , T2 second ) {
613+ return new ComplementRelation <T1 , T2 >(domain , new SingletonRelation <T1 , T2 >(first , second ));
614+ }
615+
515616 /** Produce a lazy transitive composition of two relations. Size-related operations have poor performance. */
516617 public static <T1 , T2 , T3 > Relation <T1 , T3 > compose (Relation <T1 , T2 > left , Relation <T2 , T3 > right ) {
517618 return new ComposedRelation <T1 , T2 , T3 >(left , right );
0 commit comments