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.io.IOException; 020import java.io.ObjectInputStream; 021import java.io.ObjectOutputStream; 022import java.io.Serializable; 023import java.util.Collection; 024import java.util.Comparator; 025import java.util.Objects; 026import java.util.SortedMap; 027import java.util.TreeMap; 028 029import org.apache.commons.collections4.Bag; 030import org.apache.commons.collections4.SortedBag; 031import org.apache.commons.collections4.multiset.TreeMultiSet; 032 033/** 034 * Implements {@link SortedBag}, using a {@link TreeMap} to provide the data storage. 035 * This is the standard implementation of a sorted bag. 036 * <p> 037 * Order will be maintained among the bag members and can be viewed through the iterator. 038 * </p> 039 * <p> 040 * A {@link Bag Bag} stores each object in the collection 041 * together with a count of occurrences. Extra methods on the interface allow multiple 042 * copies of an object to be added or removed at once. It is important to read the interface 043 * Javadoc carefully as several methods violate the {@link Collection} interface specification. 044 * </p> 045 * <p> 046 * <strong>Note that TreeBag is not synchronized and is not thread-safe.</strong> 047 * If you wish to use this bag from multiple threads concurrently, you must use 048 * appropriate synchronization. The simplest approach is to wrap this bag using 049 * {@link org.apache.commons.collections4.BagUtils#synchronizedSortedBag(SortedBag)}. 050 * Unsynchronized concurrent modification can corrupt the structure of the backing 051 * {@link TreeMap}, and a malformed tree may cause subsequent operations, including 052 * reads, to enter an infinite loop. 053 * </p> 054 * 055 * @param <E> The type of elements in this bag 056 * @since 3.0 (previously in main package v2.0) 057 * @deprecated Since 4.6.0, use {@link TreeMultiSet} instead. 058 */ 059@Deprecated 060public class TreeBag<E> extends AbstractMapBag<E> implements SortedBag<E>, Serializable { 061 062 /** Serial version lock */ 063 private static final long serialVersionUID = -7740146511091606676L; 064 065 /** 066 * Constructs an empty {@link TreeBag}. 067 */ 068 public TreeBag() { 069 super(new TreeMap<>()); 070 } 071 072 /** 073 * Constructs a {@link TreeBag} containing all the members of the 074 * specified collection. 075 * 076 * @param coll The collection to copy into the bag 077 */ 078 public TreeBag(final Collection<? extends E> coll) { 079 this(); 080 addAll(coll); 081 } 082 083 /** 084 * Constructs an empty bag that maintains order on its unique representative 085 * members according to the given {@link Comparator}. 086 * 087 * @param comparator The comparator to use 088 */ 089 public TreeBag(final Comparator<? super E> comparator) { 090 super(new TreeMap<>(comparator)); 091 } 092 093 /** 094 * Constructs a bag containing all the members of the given Iterable. 095 * 096 * @param iterable An iterable to copy into this bag. 097 * @since 4.5.0-M3 098 */ 099 public TreeBag(final Iterable<? extends E> iterable) { 100 super(new TreeMap<>(), iterable); 101 } 102 103 /** 104 * {@inheritDoc} 105 * 106 * @throws IllegalArgumentException if the object to be added does not implement 107 * {@link Comparable} and the {@link TreeBag} is using natural ordering 108 * @throws NullPointerException if the specified key is null and this bag uses 109 * natural ordering, or its comparator does not permit null keys 110 */ 111 @Override 112 public boolean add(final E object) { 113 if (comparator() == null && !(object instanceof Comparable)) { 114 Objects.requireNonNull(object, "object"); 115 throw new IllegalArgumentException("Objects of type " + object.getClass() + " cannot be added to " + 116 "a naturally ordered TreeBag as it does not implement Comparable"); 117 } 118 return super.add(object); 119 } 120 121 @Override 122 public Comparator<? super E> comparator() { 123 return getMap().comparator(); 124 } 125 126 @Override 127 public E first() { 128 return getMap().firstKey(); 129 } 130 131 @Override 132 protected SortedMap<E, AbstractMapBag.MutableInteger> getMap() { 133 return (SortedMap<E, AbstractMapBag.MutableInteger>) super.getMap(); 134 } 135 136 @Override 137 public E last() { 138 return getMap().lastKey(); 139 } 140 141 /** 142 * Deserializes the bag in using a custom routine. 143 * 144 * @param in The input stream 145 * @throws IOException Thrown if an error occurs while reading from the stream 146 * @throws ClassNotFoundException if an object read from the stream cannot be loaded 147 */ 148 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { 149 in.defaultReadObject(); 150 @SuppressWarnings("unchecked") // This will fail at runtime if the stream is incorrect 151 final Comparator<? super E> comp = (Comparator<? super E>) in.readObject(); 152 super.doReadObject(new TreeMap<>(comp), in); 153 } 154 155 /** 156 * Serializes this object to an ObjectOutputStream. 157 * 158 * @param out The target ObjectOutputStream. 159 * @throws IOException thrown when an I/O errors occur writing to the target stream. 160 */ 161 private void writeObject(final ObjectOutputStream out) throws IOException { 162 out.defaultWriteObject(); 163 out.writeObject(comparator()); 164 super.doWriteObject(out); 165 } 166 167}