001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4.bag; 018 019import java.util.Set; 020 021import org.apache.commons.collections4.Bag; 022import org.apache.commons.collections4.Transformer; 023import org.apache.commons.collections4.collection.TransformedCollection; 024import org.apache.commons.collections4.multiset.TransformedMultiSet; 025import org.apache.commons.collections4.set.TransformedSet; 026 027/** 028 * Decorates another {@link Bag} to transform objects that are added. 029 * <p> 030 * The add methods are affected by this class. 031 * Thus objects must be removed or searched for using their transformed form. 032 * For example, if the transformation converts Strings to Integers, you must 033 * use the Integer form to remove objects. 034 * </p> 035 * <p> 036 * This class is Serializable from Commons Collections 3.1. 037 * </p> 038 * 039 * @param <E> The type of elements in this bag 040 * @since 3.0 041 * @deprecated Since 4.6.0, use {@link TransformedMultiSet} instead. 042 */ 043@Deprecated 044public class TransformedBag<E> extends TransformedCollection<E> implements Bag<E> { 045 046 /** Serialization version */ 047 private static final long serialVersionUID = 5421170911299074185L; 048 049 /** 050 * Factory method to create a transforming bag that will transform 051 * existing contents of the specified bag. 052 * <p> 053 * If there are any elements already in the bag being decorated, they 054 * will be transformed by this method. 055 * Contrast this with {@link #transformingBag(Bag, Transformer)}. 056 * 057 * @param <E> The type of the elements in the bag 058 * @param bag The bag to decorate, must not be null 059 * @param transformer The transformer to use for conversion, must not be null 060 * @return A new transformed Bag 061 * @throws NullPointerException if bag or transformer is null 062 * @since 4.0 063 */ 064 public static <E> Bag<E> transformedBag(final Bag<E> bag, final Transformer<? super E, ? extends E> transformer) { 065 final TransformedBag<E> decorated = new TransformedBag<>(bag, transformer); 066 if (!bag.isEmpty()) { 067 @SuppressWarnings("unchecked") // Bag is of type E 068 final E[] values = (E[]) bag.toArray(); // NOPMD - false positive for generics 069 bag.clear(); 070 for (final E value : values) { 071 decorated.decorated().add(transformer.apply(value)); 072 } 073 } 074 return decorated; 075 } 076 077 /** 078 * Factory method to create a transforming bag. 079 * <p> 080 * If there are any elements already in the bag being decorated, they 081 * are NOT transformed. Contrast this with {@link #transformedBag(Bag, Transformer)}. 082 * 083 * @param <E> The type of the elements in the bag 084 * @param bag The bag to decorate, must not be null 085 * @param transformer The transformer to use for conversion, must not be null 086 * @return A new transformed Bag 087 * @throws NullPointerException if bag or transformer is null 088 * @since 4.0 089 */ 090 public static <E> Bag<E> transformingBag(final Bag<E> bag, final Transformer<? super E, ? extends E> transformer) { 091 return new TransformedBag<>(bag, transformer); 092 } 093 094 /** 095 * Constructor that wraps (not copies). 096 * <p> 097 * If there are any elements already in the bag being decorated, they 098 * are NOT transformed. 099 * 100 * @param bag The bag to decorate, must not be null 101 * @param transformer The transformer to use for conversion, must not be null 102 * @throws NullPointerException if bag or transformer is null 103 */ 104 protected TransformedBag(final Bag<E> bag, final Transformer<? super E, ? extends E> transformer) { 105 super(bag, transformer); 106 } 107 108 @Override 109 public boolean add(final E object, final int nCopies) { 110 return getBag().add(transform(object), nCopies); 111 } 112 113 @Override 114 public boolean equals(final Object object) { 115 return object == this || decorated().equals(object); 116 } 117 118 /** 119 * Gets the decorated bag. 120 * 121 * @return The decorated bag 122 */ 123 protected Bag<E> getBag() { 124 return (Bag<E>) decorated(); 125 } 126 127 @Override 128 public int getCount(final Object object) { 129 return getBag().getCount(object); 130 } 131 132 @Override 133 public int hashCode() { 134 return decorated().hashCode(); 135 } 136 137 @Override 138 public boolean remove(final Object object, final int nCopies) { 139 return getBag().remove(object, nCopies); 140 } 141 142 @Override 143 public Set<E> uniqueSet() { 144 final Set<E> set = getBag().uniqueSet(); 145 return TransformedSet.<E>transformingSet(set, transformer); 146 } 147 148}