Commit cc39626f by Patryk Czarnik

Wrzutka przykładowych kodów

parents
/target/
/.idea/
/*.iml
This diff is collapsed. Click to expand it.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>xyz</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
\ No newline at end of file
package emps;
import java.time.LocalDate;
import java.util.Objects;
public class Employee {
public Employee(int employeeId, String firstName, String lastName, String jobTitle, int salary, LocalDate hireDate, String department, String streetAddress, String postalCode, String city, String country) {
this.employeeId = employeeId;
this.firstName = firstName;
this.lastName = lastName;
this.jobTitle = jobTitle;
this.salary = salary;
this.hireDate = hireDate;
this.department = department;
this.streetAddress = streetAddress;
this.postalCode = postalCode;
this.city = city;
this.country = country;
}
private int employeeId;
private String firstName;
private String lastName;
private String jobTitle;
private int salary;
private LocalDate hireDate;
private String department;
private String streetAddress;
private String postalCode;
private String city;
private String country;
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public LocalDate getHireDate() {
return hireDate;
}
public void setHireDate(LocalDate hireDate) {
this.hireDate = hireDate;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getStreetAddress() {
return streetAddress;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "Employee{" +
"employeeId=" + employeeId +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", jobTitle='" + jobTitle + '\'' +
", salary=" + salary +
", hireDate=" + hireDate +
", department='" + department + '\'' +
", streetAddress='" + streetAddress + '\'' +
", postalCode='" + postalCode + '\'' +
", city='" + city + '\'' +
", country='" + country + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return employeeId == employee.employeeId && salary == employee.salary && Objects.equals(firstName, employee.firstName) && Objects.equals(lastName, employee.lastName) && Objects.equals(jobTitle, employee.jobTitle) && Objects.equals(hireDate, employee.hireDate) && Objects.equals(department, employee.department) && Objects.equals(streetAddress, employee.streetAddress) && Objects.equals(postalCode, employee.postalCode) && Objects.equals(city, employee.city) && Objects.equals(country, employee.country);
}
@Override
public int hashCode() {
return Objects.hash(employeeId, firstName, lastName, jobTitle, salary, hireDate, department, streetAddress, postalCode, city, country);
}
}
package emps;
import java.util.List;
import java.util.stream.Collectors;
public class F1_Wypisz {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
emps.forEach(emp -> System.out.println(emp));
System.out.println();
emps.forEach(System.out::println);
// Wypisać same nazwiska
emps.forEach(employee -> System.out.print(employee.getLastName() + "; "));
System.out.println();
emps.stream()
.map(Employee::getLastName)
.forEach(System.out::println);
System.out.println();
String txt = emps.stream()
.map(Employee::getLastName)
.sorted()
.collect(Collectors.joining(", "));
System.out.println(txt);
}
}
package emps;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class F3_Grupowanie_Stream {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
Map<String, List<Employee>> grupy = emps.stream().collect(Collectors.groupingBy(Employee::getCity));
grupy.forEach((city, lista) -> {
System.out.println("Pracownicy z miasta " + city +":");
lista.forEach(emp -> {
System.out.println(" * " + emp.getFirstName() + " " + emp.getLastName());
});
System.out.println();
});
}
}
package emps;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class F4_Grupowanie_Avg {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
Map<String, Double> srednie = emps.stream().collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getSalary)));
srednie.forEach((city, srednia) -> {
System.out.printf("%30s : %8.2f\n", city, srednia);
});
}
}
package emps;
import java.io.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class ObslugaPliku {
public static List<Employee> wczytaj(String path) {
return wczytaj(new File(path));
}
public static List<Employee> wczytaj(File file) {
List<Employee> emps = new ArrayList<>();
try (BufferedReader input = new BufferedReader(new FileReader(file))) {
input.readLine();
String line;
while((line = input.readLine()) != null) {
String[] t = line.split(";", 11);
Employee emp = new Employee(Integer.parseInt(t[0]), t[1], t[2], t[3], Integer.parseInt(t[4]), LocalDate.parse(t[5]), t[6], t[7], t[8], t[9], t[10]);
emps.add(emp);
}
} catch (IOException e) {
e.printStackTrace();
}
return emps;
}
}
package emps;
import java.util.List;
public class P1_Wypisz {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
for (Employee emp : emps) {
System.out.println(emp);
}
}
}
package emps;
import javax.swing.*;
import java.util.List;
import java.util.Objects;
public class P2_Filtruj {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
String miasto = JOptionPane.showInputDialog("Podaj miasto");
int count = 0;
for (Employee emp : emps) {
if (Objects.equals(emp.getCity(), miasto)) {
System.out.println(emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary());
count++;
}
}
System.out.println("Count: " + count);
}
}
package emps;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class P3_Grupowanie {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
// city → count
Map<String, Integer> cnt = new HashMap<>();
Map<String, Integer> sum = new HashMap<>();
for (Employee emp : emps) {
final String city = emp.getCity();
if (cnt.containsKey(city)) {
Integer oldCnt = cnt.get(city);
cnt.put(city, oldCnt+1);
Integer oldSum = sum.get(city);
sum.put(city, oldSum+emp.getSalary());
} else {
cnt.put(city, 1);
sum.put(city, emp.getSalary());
}
}
for (Map.Entry<String, Integer> entry : cnt.entrySet()) {
System.out.printf("%30s : %2d\n", entry.getKey(), entry.getValue());
}
System.out.println("-------");
for (String city : cnt.keySet()) {
int ile = cnt.get(city);
int suma = sum.get(city);
double srednia = (double) suma / ile;
System.out.printf("%30s : %8.2f\n", city, srednia);
}
}
}
package emps;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class P4_Grupowanie_default {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
// city → count
Map<String, Integer> cnt = new HashMap<>();
Map<String, Integer> sum = new HashMap<>();
for (Employee emp : emps) {
final String city = emp.getCity();
Integer oldCnt = cnt.getOrDefault(city, 0);
cnt.put(city, oldCnt + 1);
Integer oldSum = sum.getOrDefault(city, 0);
sum.put(city, oldSum + emp.getSalary());
}
for (String city : cnt.keySet()) {
int ile = cnt.get(city);
int suma = sum.get(city);
double srednia = (double) suma / ile;
System.out.printf("%30s : %8.2f\n", city, srednia);
}
}
}
package emps;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class P5_Grupowanie_merge {
public static void main(String[] args) {
List<Employee> emps = ObslugaPliku.wczytaj("emps.csv");
// city → count
Map<String, Integer> cnt = new HashMap<>();
Map<String, Integer> sum = new HashMap<>();
for (Employee emp : emps) {
final String city = emp.getCity();
// cnt.merge(city, 1, (old, value) -> old+value);
cnt.merge(city, 1, Integer::sum);
sum.merge(city, emp.getSalary(), Integer::sum);
}
for (String city : cnt.keySet()) {
int ile = cnt.get(city);
int suma = sum.get(city);
double srednia = (double) suma / ile;
System.out.printf("%30s : %8.2f\n", city, srednia);
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.ArrayList;
import java.util.EmptyStackException;
/**
* An implementation of the {@link java.util.Stack} API that is based on an
* {@code ArrayList} instead of a {@code Vector}, so it is not
* synchronized to protect against multi-threaded access. The implementation
* is therefore operates faster in environments where you do not need to
* worry about multiple thread contention.
* <p>
* The removal order of an {@code ArrayStack} is based on insertion
* order: The most recently added element is removed first. The iteration
* order is <i>not</i> the same as the removal order. The iterator returns
* elements from the bottom up.
* </p>
* <p>
* Unlike {@code Stack}, {@code ArrayStack} accepts null entries.
* <p>
* <b>Note:</b> From version 4.0 onwards, this class does not implement the
* removed {@code Buffer} interface anymore.
* </p>
*
* @param <E> the type of elements in this list
* @see java.util.Stack
* @since 1.0
* @deprecated use {@link java.util.ArrayDeque} instead (available from Java 1.6)
*/
@Deprecated
public class ArrayStack<E> extends ArrayList<E> {
/** Ensure serialization compatibility */
private static final long serialVersionUID = 2130079159931574599L;
/**
* Constructs a new empty {@code ArrayStack}. The initial size
* is controlled by {@code ArrayList} and is currently 10.
*/
public ArrayStack() {
}
/**
* Constructs a new empty {@code ArrayStack} with an initial size.
*
* @param initialSize the initial size to use
* @throws IllegalArgumentException if the specified initial size
* is negative
*/
public ArrayStack(final int initialSize) {
super(initialSize);
}
/**
* Return {@code true} if this stack is currently empty.
* <p>
* This method exists for compatibility with {@code java.util.Stack}.
* New users of this class should use {@code isEmpty} instead.
*
* @return true if the stack is currently empty
*/
public boolean empty() {
return isEmpty();
}
/**
* Returns the top item off of this stack without removing it.
*
* @return the top item on the stack
* @throws EmptyStackException if the stack is empty
*/
public E peek() throws EmptyStackException {
final int n = size();
if (n <= 0) {
throw new EmptyStackException();
}
return get(n - 1);
}
/**
* Returns the n'th item down (zero-relative) from the top of this
* stack without removing it.
*
* @param n the number of items down to go
* @return the n'th item on the stack, zero relative
* @throws EmptyStackException if there are not enough items on the
* stack to satisfy this request
*/
public E peek(final int n) throws EmptyStackException {
final int m = (size() - n) - 1;
if (m < 0) {
throw new EmptyStackException();
}
return get(m);
}
/**
* Pops the top item off of this stack and return it.
*
* @return the top item on the stack
* @throws EmptyStackException if the stack is empty
*/
public E pop() throws EmptyStackException {
final int n = size();
if (n <= 0) {
throw new EmptyStackException();
}
return remove(n - 1);
}
/**
* Pushes a new item onto the top of this stack. The pushed item is also
* returned. This is equivalent to calling {@code add}.
*
* @param item the item to be added
* @return the item just pushed
*/
public E push(final E item) {
add(item);
return item;
}
/**
* Returns the one-based position of the distance from the top that the
* specified object exists on this stack, where the top-most element is
* considered to be at distance {@code 1}. If the object is not
* present on the stack, return {@code -1} instead. The
* {@code equals()} method is used to compare to the items
* in this stack.
*
* @param object the object to be searched for
* @return the 1-based depth into the stack of the object, or -1 if not found
*/
public int search(final Object object) {
int i = size() - 1; // Current index
int n = 1; // Current distance
while (i >= 0) {
final Object current = get(i);
if ((object == null && current == null) ||
(object != null && object.equals(current))) {
return n;
}
i--;
n++;
}
return -1;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* <p>
* Operations on arrays, primitive arrays (like {@code int[]}) and primitive wrapper arrays (like {@code Integer[]}).
* </p>
* <p>
* This class tries to handle {@code null} input gracefully. An exception will not be thrown for a {@code null} array
* input. However, an Object array that contains a {@code null} element may throw an exception. Each method documents
* its behavior.
* </p>
* <p>
* Package private, might move to an internal package if this needs to be public.
* </p>
* <p>
* #ThreadSafe#
* </p>
*
* @since 4.2 (Copied from Apache Commons Lang.)
*
*/
class ArrayUtils {
/**
* Don't allow instances.
*/
private ArrayUtils() {}
/**
* <p>
* Checks if the object is in the given array.
* </p>
*
* <p>
* The method returns {@code false} if a {@code null} array is passed in.
* </p>
*
* @param array
* the array to search through
* @param objectToFind
* the object to find
* @return {@code true} if the array contains the object
*/
static boolean contains(final Object[] array, final Object objectToFind) {
return indexOf(array, objectToFind) != CollectionUtils.INDEX_NOT_FOUND;
}
/**
* <p>
* Finds the index of the given object in the array.
* </p>
*
* <p>
* This method returns {@link CollectionUtils#INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
* </p>
*
* @param array
* the array to search through for the object, may be {@code null}
* @param objectToFind
* the object to find, may be {@code null}
* @return the index of the object within the array, {@link CollectionUtils#INDEX_NOT_FOUND} ({@code -1}) if not found or
* {@code null} array input
*/
static <T> int indexOf(final T[] array, final Object objectToFind) {
return indexOf(array, objectToFind, 0);
}
/**
* <p>
* Finds the index of the given object in the array starting at the given index.
* </p>
*
* <p>
* This method returns {@link CollectionUtils#INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
* </p>
*
* <p>
* A negative startIndex is treated as zero. A startIndex larger than the array length will return
* {@link CollectionUtils#INDEX_NOT_FOUND} ({@code -1}).
* </p>
*
* @param array
* the array to search through for the object, may be {@code null}
* @param objectToFind
* the object to find, may be {@code null}
* @param startIndex
* the index to start searching at
* @return the index of the object within the array starting at the index, {@link CollectionUtils#INDEX_NOT_FOUND} ({@code -1}) if
* not found or {@code null} array input
*/
static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
if (array == null) {
return CollectionUtils.INDEX_NOT_FOUND;
}
if (startIndex < 0) {
startIndex = 0;
}
if (objectToFind == null) {
for (int i = startIndex; i < array.length; i++) {
if (array[i] == null) {
return i;
}
}
} else {
for (int i = startIndex; i < array.length; i++) {
if (objectToFind.equals(array[i])) {
return i;
}
}
}
return CollectionUtils.INDEX_NOT_FOUND;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* Defines a collection that counts the number of times an object appears in
* the collection.
* <p>
* Suppose you have a Bag that contains {@code {a, a, b, c}}.
* Calling {@link #getCount(Object)} on {@code a} would return 2, while
* calling {@link #uniqueSet()} would return {@code {a, b, c}}.
* </p>
* <p>
* <i>NOTE: This interface violates the {@link Collection} contract.</i>
* The behavior specified in many of these methods is <i>not</i> the same
* as the behavior specified by {@code Collection}.
* The noncompliant methods are clearly marked with "(Violation)".
* Exercise caution when using a bag as a {@code Collection}.
* </p>
* <p>
* This violation resulted from the original specification of this interface.
* In an ideal world, the interface would be changed to fix the problems, however
* it has been decided to maintain backwards compatibility instead.
* </p>
*
* @param <E> the type of elements in this bag
* @since 2.0
*/
public interface Bag<E> extends Collection<E> {
/**
* Returns the number of occurrences (cardinality) of the given
* object currently in the bag. If the object does not exist in the
* bag, return 0.
*
* @param object the object to search for
* @return the number of occurrences of the object, zero if not found
*/
int getCount(Object object);
/**
* <i>(Violation)</i>
* Adds one copy of the specified object to the Bag.
* <p>
* If the object is already in the {@link #uniqueSet()} then increment its
* count as reported by {@link #getCount(Object)}. Otherwise add it to the
* {@link #uniqueSet()} and report its count as 1.
* </p>
* <p>
* Since this method always increases the size of the bag,
* according to the {@link Collection#add(Object)} contract, it
* should always return {@code true}. Since it sometimes returns
* {@code false}, this method violates the contract.
* </p>
*
* @param object the object to add
* @return {@code true} if the object was not already in the {@code uniqueSet}
*/
@Override
boolean add(E object);
/**
* Adds {@code nCopies} copies of the specified object to the Bag.
* <p>
* If the object is already in the {@link #uniqueSet()} then increment its
* count as reported by {@link #getCount(Object)}. Otherwise add it to the
* {@link #uniqueSet()} and report its count as {@code nCopies}.
* </p>
*
* @param object the object to add
* @param nCopies the number of copies to add
* @return {@code true} if the object was not already in the {@code uniqueSet}
*/
boolean add(E object, int nCopies);
/**
* <i>(Violation)</i>
* Removes all occurrences of the given object from the bag.
* <p>
* This will also remove the object from the {@link #uniqueSet()}.
* </p>
* <p>
* According to the {@link Collection#remove(Object)} method,
* this method should only remove the <i>first</i> occurrence of the
* given object, not <i>all</i> occurrences.
* </p>
*
* @param object the object to remove
* @return {@code true} if this call changed the collection
*/
@Override
boolean remove(Object object);
/**
* Removes {@code nCopies} copies of the specified object from the Bag.
* <p>
* If the number of copies to remove is greater than the actual number of
* copies in the Bag, no error is thrown.
* </p>
*
* @param object the object to remove
* @param nCopies the number of copies to remove
* @return {@code true} if this call changed the collection
*/
boolean remove(Object object, int nCopies);
/**
* Returns a {@link Set} of unique elements in the Bag.
* <p>
* Uniqueness constraints are the same as those in {@link java.util.Set}.
* </p>
*
* @return the Set of unique Bag elements
*/
Set<E> uniqueSet();
/**
* Returns the total number of items in the bag across all types.
*
* @return the total size of the Bag
*/
@Override
int size();
/**
* <i>(Violation)</i>
* Returns {@code true} if the bag contains all elements in
* the given collection, respecting cardinality. That is, if the
* given collection {@code coll} contains {@code n} copies
* of a given object, calling {@link #getCount(Object)} on that object must
* be {@code &gt;= n} for all {@code n} in {@code coll}.
*
* <p>
* The {@link Collection#containsAll(Collection)} method specifies
* that cardinality should <i>not</i> be respected; this method should
* return true if the bag contains at least one of every object contained
* in the given collection.
* </p>
*
* @param coll the collection to check against
* @return {@code true} if the Bag contains all the collection
*/
@Override
boolean containsAll(Collection<?> coll);
/**
* <i>(Violation)</i>
* Remove all elements represented in the given collection,
* respecting cardinality. That is, if the given collection
* {@code coll} contains {@code n} copies of a given object,
* the bag will have {@code n} fewer copies, assuming the bag
* had at least {@code n} copies to begin with.
*
* <p>
* The {@link Collection#removeAll(Collection)} method specifies
* that cardinality should <i>not</i> be respected; this method should
* remove <i>all</i> occurrences of every object contained in the
* given collection.
* </p>
*
* @param coll the collection to remove
* @return {@code true} if this call changed the collection
*/
@Override
boolean removeAll(Collection<?> coll);
/**
* <i>(Violation)</i>
* Remove any members of the bag that are not in the given
* collection, respecting cardinality. That is, if the given
* collection {@code coll} contains {@code n} copies of a
* given object and the bag has {@code m &gt; n} copies, then
* delete {@code m - n} copies from the bag. In addition, if
* {@code e} is an object in the bag but
* {@code !coll.contains(e)}, then remove {@code e} and any
* of its copies.
*
* <p>
* The {@link Collection#retainAll(Collection)} method specifies
* that cardinality should <i>not</i> be respected; this method should
* keep <i>all</i> occurrences of every object contained in the
* given collection.
* </p>
*
* @param coll the collection to retain
* @return {@code true} if this call changed the collection
*/
@Override
boolean retainAll(Collection<?> coll);
/**
* Returns an {@link Iterator} over the entire set of members,
* including copies due to cardinality. This iterator is fail-fast
* and will not tolerate concurrent modifications.
*
* @return iterator over all elements in the Bag
*/
@Override
Iterator<E> iterator();
// The following is not part of the formal Bag interface, however where possible
// Bag implementations should follow these comments.
// /**
// * Compares this Bag to another.
// * This Bag equals another Bag if it contains the same number of occurrences of
// * the same elements.
// * This equals definition is compatible with the Set interface.
// *
// * @param obj the Bag to compare to
// * @return true if equal
// */
// boolean equals(Object obj);
//
// /**
// * Gets a hash code for the Bag compatible with the definition of equals.
// * The hash code is defined as the sum total of a hash code for each element.
// * The per element hash code is defined as
// * {@code (e==null ? 0 : e.hashCode()) ^ noOccurrences)}.
// * This hash code definition is compatible with the Set interface.
// *
// * @return the hash code of the Bag
// */
// int hashCode();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Set;
/**
* Defines a map that allows bidirectional lookup between key and values.
* <p>
* This extended {@code Map} represents a mapping where a key may
* lookup a value and a value may lookup a key with equal ease.
* This interface extends {@code Map} and so may be used anywhere a map
* is required. The interface provides an inverse map view, enabling
* full access to both directions of the {@code BidiMap}.
* </p>
* <p>
* Implementations should allow a value to be looked up from a key and
* a key to be looked up from a value with equal performance.
* </p>
* <p>
* This map enforces the restriction that there is a 1:1 relation between
* keys and values, meaning that multiple keys cannot map to the same value.
* This is required so that "inverting" the map results in a map without
* duplicate keys. See the {@link #put} method description for more information.
* </p>
*
* @param <K> the type of the keys in the map
* @param <V> the type of the values in the map
*
* @since 3.0
*/
public interface BidiMap<K, V> extends IterableMap<K, V> {
/**
* Puts the key-value pair into the map, replacing any previous pair.
* <p>
* When adding a key-value pair, the value may already exist in the map
* against a different key. That mapping is removed, to ensure that the
* value only occurs once in the inverse map.
* </p>
* <pre>
* BidiMap map1 = new DualHashBidiMap();
* map.put("A","B"); // contains A mapped to B, as per Map
* map.put("A","C"); // contains A mapped to C, as per Map
*
* BidiMap map2 = new DualHashBidiMap();
* map.put("A","B"); // contains A mapped to B, as per Map
* map.put("C","B"); // contains C mapped to B, key A is removed
* </pre>
*
* @param key the key to store
* @param value the value to store
* @return the previous value mapped to this key
*
* @throws UnsupportedOperationException if the {@code put} method is not supported
* @throws ClassCastException (optional) if the map limits the type of the
* value and the specified value is inappropriate
* @throws IllegalArgumentException (optional) if the map limits the values
* in some way and the value was invalid
* @throws NullPointerException (optional) if the map limits the values to
* non-null and null was specified
*/
@Override
V put(K key, V value);
/**
* Gets the key that is currently mapped to the specified value.
* <p>
* If the value is not contained in the map, {@code null} is returned.
* </p>
* <p>
* Implementations should seek to make this method perform equally as well
* as {@code get(Object)}.
* </p>
*
* @param value the value to find the key for
* @return the mapped key, or {@code null} if not found
*
* @throws ClassCastException (optional) if the map limits the type of the
* value and the specified value is inappropriate
* @throws NullPointerException (optional) if the map limits the values to
* non-null and null was specified
*/
K getKey(Object value);
/**
* Removes the key-value pair that is currently mapped to the specified
* value (optional operation).
* <p>
* If the value is not contained in the map, {@code null} is returned.
* </p>
* <p>
* Implementations should seek to make this method perform equally as well
* as {@code remove(Object)}.
* </p>
*
* @param value the value to find the key-value pair for
* @return the key that was removed, {@code null} if nothing removed
*
* @throws ClassCastException (optional) if the map limits the type of the
* value and the specified value is inappropriate
* @throws NullPointerException (optional) if the map limits the values to
* non-null and null was specified
* @throws UnsupportedOperationException if this method is not supported
* by the implementation
*/
K removeValue(Object value);
/**
* Gets a view of this map where the keys and values are reversed.
* <p>
* Changes to one map will be visible in the other and vice versa.
* This enables both directions of the map to be accessed as a {@code Map}.
* </p>
* <p>
* Implementations should seek to avoid creating a new object every time this
* method is called. See {@code AbstractMap.values()} etc. Calling this
* method on the inverse map should return the original.
* </p>
*
* @return an inverted bidirectional map
*/
BidiMap<V, K> inverseBidiMap();
/**
* Returns a {@link Set} view of the values contained in this map.
* The set is backed by the map, so changes to the map are reflected
* in the set, and vice-versa. If the map is modified while an iteration
* over the set is in progress (except through the iterator's own
* {@code remove} operation), the results of the iteration are undefined.
* The set supports element removal, which removes the corresponding
* mapping from the map, via the {@code Iterator.remove},
* {@code Collection.remove}, {@code removeAll},
* {@code retainAll} and {@code clear} operations. It does not
* support the {@code add} or {@code addAll} operations.
*
* @return a set view of the values contained in this map
*/
@Override
Set<V> values();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Collection;
/**
* Defines a collection that is bounded in size.
* <p>
* The size of the collection can vary, but it can never exceed a preset
* maximum number of elements. This interface allows the querying of details
* associated with the maximum number of elements.
* </p>
*
* @see CollectionUtils#isFull
* @see CollectionUtils#maxSize
*
* @param <E> the type of elements in this collection
* @since 3.0
*/
public interface BoundedCollection<E> extends Collection<E> {
/**
* Returns true if this collection is full and no new elements can be added.
*
* @return {@code true} if the collection is full.
*/
boolean isFull();
/**
* Gets the maximum size of the collection (the bound).
*
* @return the maximum number of elements the collection can hold.
*/
int maxSize();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a map that is bounded in size.
* <p>
* The size of the map can vary, but it can never exceed a preset
* maximum number of elements. This interface allows the querying of details
* associated with the maximum number of elements.
* </p>
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
* @since 3.0
*/
public interface BoundedMap<K, V> extends IterableMap<K, V> {
/**
* Returns true if this map is full and no new elements can be added.
*
* @return {@code true} if the map is full
*/
boolean isFull();
/**
* Gets the maximum size of the map (the bound).
*
* @return the maximum number of elements the map can hold
*/
int maxSize();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a functor interface implemented by classes that do something.
* <p>
* A {@code Closure} represents a block of code which is executed from
* inside some block, function or iteration. It operates an input object.
* </p>
* <p>
* Standard implementations of common closures are provided by
* {@link ClosureUtils}. These include method invocation and for/while loops.
* </p>
*
* @param <T> the type that the closure acts on
* @since 1.0
*/
@FunctionalInterface
public interface Closure<T> {
/**
* Performs an action on the specified input object.
*
* @param input the input to execute on
* @throws ClassCastException (runtime) if the input is the wrong class
* @throws IllegalArgumentException (runtime) if the input is invalid
* @throws FunctorException (runtime) if any other error occurs
*/
void execute(T input);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Collection;
import java.util.Comparator;
import java.util.Objects;
import org.apache.commons.collections4.comparators.BooleanComparator;
import org.apache.commons.collections4.comparators.ComparableComparator;
import org.apache.commons.collections4.comparators.ComparatorChain;
import org.apache.commons.collections4.comparators.NullComparator;
import org.apache.commons.collections4.comparators.ReverseComparator;
import org.apache.commons.collections4.comparators.TransformingComparator;
/**
* Provides convenient static utility methods for <Code>Comparator</Code>
* objects.
* <p>
* Most of the functionality in this class can also be found in the
* {@code comparators} package. This class merely provides a
* convenient central place if you have use for more than one class
* in the {@code comparators} subpackage.
* </p>
*
* @since 2.1
*/
public class ComparatorUtils {
private static final Comparator[] EMPTY_COMPARATOR_ARRAY = {};
/**
* Don't allow instances.
*/
private ComparatorUtils() {}
/**
* Comparator for natural sort order.
*
* @see ComparableComparator#comparableComparator()
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) // explicit type needed for Java 1.5 compilation
public static final Comparator NATURAL_COMPARATOR = ComparableComparator.<Comparable>comparableComparator();
/**
* Gets a comparator that uses the natural order of the objects.
*
* @param <E> the object type to compare
* @return a comparator which uses natural order
*/
@SuppressWarnings("unchecked")
public static <E extends Comparable<? super E>> Comparator<E> naturalComparator() {
return NATURAL_COMPARATOR;
}
/**
* Gets a comparator that compares using an array of {@link Comparator}s, applied
* in sequence until one returns not equal or the array is exhausted.
*
* @param <E> the object type to compare
* @param comparators the comparators to use, not null or empty or containing nulls
* @return a {@link ComparatorChain} formed from the input comparators
* @throws NullPointerException if comparators array is null or contains a null
* @see ComparatorChain
*/
public static <E> Comparator<E> chainedComparator(final Comparator<E>... comparators) {
final ComparatorChain<E> chain = new ComparatorChain<>();
for (final Comparator<E> comparator : comparators) {
chain.addComparator(Objects.requireNonNull(comparator, "comparator"));
}
return chain;
}
/**
* Gets a comparator that compares using a collection of {@link Comparator}s,
* applied in (default iterator) sequence until one returns not equal or the
* collection is exhausted.
*
* @param <E> the object type to compare
* @param comparators the comparators to use, not null or empty or containing nulls
* @return a {@link ComparatorChain} formed from the input comparators
* @throws NullPointerException if comparators collection is null or contains a null
* @throws ClassCastException if the comparators collection contains the wrong object type
* @see ComparatorChain
*/
@SuppressWarnings("unchecked")
public static <E> Comparator<E> chainedComparator(final Collection<Comparator<E>> comparators) {
return chainedComparator(
comparators.toArray(EMPTY_COMPARATOR_ARRAY)
);
}
/**
* Gets a comparator that reverses the order of the given comparator.
*
* @param <E> the object type to compare
* @param comparator the comparator to reverse
* @return a comparator that reverses the order of the input comparator
* @see ReverseComparator
*/
public static <E> Comparator<E> reversedComparator(final Comparator<E> comparator) {
return new ReverseComparator<>(comparator);
}
/**
* Gets a Comparator that can sort Boolean objects.
* <p>
* The parameter specifies whether true or false is sorted first.
* </p>
* <p>
* The comparator throws NullPointerException if a null value is compared.
* </p>
*
* @param trueFirst when {@code true}, sort
* {@code true} {@link Boolean}s before
* {@code false} {@link Boolean}s.
* @return a comparator that sorts booleans
*/
public static Comparator<Boolean> booleanComparator(final boolean trueFirst) {
return BooleanComparator.booleanComparator(trueFirst);
}
/**
* Gets a Comparator that controls the comparison of {@code null} values.
* <p>
* The returned comparator will consider a null value to be less than
* any nonnull value, and equal to any other null value. Two nonnull
* values will be evaluated with the given comparator.
* </p>
*
* @param <E> the object type to compare
* @param comparator the comparator that wants to allow nulls
* @return a version of that comparator that allows nulls
* @see NullComparator
*/
@SuppressWarnings("unchecked")
public static <E> Comparator<E> nullLowComparator(Comparator<E> comparator) {
if (comparator == null) {
comparator = NATURAL_COMPARATOR;
}
return new NullComparator<>(comparator, false);
}
/**
* Gets a Comparator that controls the comparison of {@code null} values.
* <p>
* The returned comparator will consider a null value to be greater than
* any nonnull value, and equal to any other null value. Two nonnull
* values will be evaluated with the given comparator.
* </p>
*
* @param <E> the object type to compare
* @param comparator the comparator that wants to allow nulls
* @return a version of that comparator that allows nulls
* @see NullComparator
*/
@SuppressWarnings("unchecked")
public static <E> Comparator<E> nullHighComparator(Comparator<E> comparator) {
if (comparator == null) {
comparator = NATURAL_COMPARATOR;
}
return new NullComparator<>(comparator, true);
}
/**
* Gets a Comparator that passes transformed objects to the given comparator.
* <p>
* Objects passed to the returned comparator will first be transformed
* by the given transformer before they are compared by the given
* comparator.
* </p>
*
* @param <I> the input object type of the transformed comparator
* @param <O> the object type of the decorated comparator
* @param comparator the sort order to use
* @param transformer the transformer to use
* @return a comparator that transforms its input objects before comparing them
* @see TransformingComparator
*/
@SuppressWarnings("unchecked")
public static <I, O> Comparator<I> transformedComparator(Comparator<O> comparator,
final Transformer<? super I, ? extends O> transformer) {
if (comparator == null) {
comparator = NATURAL_COMPARATOR;
}
return new TransformingComparator<>(transformer, comparator);
}
/**
* Returns the smaller of the given objects according to the given
* comparator, returning the second object if the comparator
* returns equal.
*
* @param <E> the object type to compare
* @param o1 the first object to compare
* @param o2 the second object to compare
* @param comparator the sort order to use
* @return the smaller of the two objects
*/
@SuppressWarnings("unchecked")
public static <E> E min(final E o1, final E o2, Comparator<E> comparator) {
if (comparator == null) {
comparator = NATURAL_COMPARATOR;
}
final int c = comparator.compare(o1, o2);
return c < 0 ? o1 : o2;
}
/**
* Returns the larger of the given objects according to the given
* comparator, returning the second object if the comparator
* returns equal.
*
* @param <E> the object type to compare
* @param o1 the first object to compare
* @param o2 the second object to compare
* @param comparator the sort order to use
* @return the larger of the two objects
*/
@SuppressWarnings("unchecked")
public static <E> E max(final E o1, final E o2, Comparator<E> comparator) {
if (comparator == null) {
comparator = NATURAL_COMPARATOR;
}
final int c = comparator.compare(o1, o2);
return c > 0 ? o1 : o2;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.commons.collections4.iterators.EnumerationIterator;
import org.apache.commons.collections4.iterators.IteratorIterable;
/**
* Provides utility methods for {@link Enumeration} instances.
*
* @since 3.0
*/
public class EnumerationUtils {
/**
* Don't allow instances.
*/
private EnumerationUtils() {
// no instances.
}
/**
* Creates an {@link Iterable} that wraps an {@link Enumeration}. The returned {@link Iterable} can be used for a
* single iteration.
*
* @param <T> the element type
* @param enumeration the enumeration to use, may not be null
* @return a new, single use {@link Iterable}
* @since 4.5
*/
public static <T> Iterable<T> asIterable(final Enumeration<T> enumeration) {
return new IteratorIterable<>(new EnumerationIterator<>(enumeration));
}
/**
* Returns the {@code index}-th value in the {@link Enumeration}, throwing
* {@code IndexOutOfBoundsException} if there is no such element.
* <p>
* The Enumeration is advanced to {@code index} (or to the end, if
* {@code index} exceeds the number of entries) as a side effect of this method.
*
* @param e the enumeration to get a value from
* @param index the index to get
* @param <T> the type of object in the {@link Enumeration}
* @return the object at the specified index
* @throws IndexOutOfBoundsException if the index is invalid
* @throws IllegalArgumentException if the object type is invalid
* @since 4.1
*/
public static <T> T get(final Enumeration<T> e, final int index) {
CollectionUtils.checkIndexBounds(index);
int i = index;
while (e.hasMoreElements()) {
i--;
if (i == -1) {
return e.nextElement();
}
e.nextElement();
}
throw new IndexOutOfBoundsException("Entry does not exist: " + i);
}
/**
* Creates a list based on an enumeration.
*
* <p>As the enumeration is traversed, an ArrayList of its values is
* created. The new list is returned.</p>
*
* @param <E> the element type
* @param enumeration the enumeration to traverse, which should not be {@code null}.
* @return a list containing all elements of the given enumeration
* @throws NullPointerException if the enumeration parameter is {@code null}.
*/
public static <E> List<E> toList(final Enumeration<? extends E> enumeration) {
return IteratorUtils.toList(new EnumerationIterator<>(enumeration));
}
/**
* Override toList(Enumeration) for StringTokenizer as it implements Enumeration&lt;Object&gt;
* for the sake of backward compatibility.
*
* @param stringTokenizer the tokenizer to convert to a {@link List}&lt;{@link String}&gt;
* @return a list containing all tokens of the given StringTokenizer
*/
public static List<String> toList(final StringTokenizer stringTokenizer) {
final List<String> result = new ArrayList<>(stringTokenizer.countTokens());
while (stringTokenizer.hasMoreTokens()) {
result.add(stringTokenizer.nextToken());
}
return result;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* An equation function, which determines equality between objects of type T.
* <p>
* It is the functional sibling of {@link java.util.Comparator}; {@link Equator} is to
* {@link Object} as {@link java.util.Comparator} is to {@link Comparable}.
* </p>
*
* @param <T> the types of object this {@link Equator} can evaluate.
* @since 4.0
*/
public interface Equator<T> {
/**
* Evaluates the two arguments for their equality.
*
* @param o1 the first object to be equated.
* @param o2 the second object to be equated.
* @return whether the two objects are equal.
*/
boolean equate(T o1, T o2);
/**
* Calculates the hash for the object, based on the method of equality used in the equate
* method. This is used for classes that delegate their {@link Object#equals(Object) equals(Object)} method to an
* Equator (and so must also delegate their {@link Object#hashCode() hashCode()} method), or for implementations
* of {@link org.apache.commons.collections4.map.HashedMap} that use an Equator for the key objects.
*
* @param o the object to calculate the hash for.
* @return the hash of the object.
*/
int hash(T o);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a functor interface implemented by classes that create objects.
* <p>
* A {@code Factory} creates an object without using an input parameter.
* If an input parameter is required, then {@link Transformer} is more appropriate.
* </p>
* <p>
* Standard implementations of common factories are provided by
* {@link FactoryUtils}. These include factories that return a constant,
* a copy of a prototype or a new instance.
* </p>
*
* @param <T> the type that the factory creates
*
* @since 2.1
*/
@FunctionalInterface
public interface Factory<T> {
/**
* Create a new object.
*
* @return a new object
* @throws FunctorException (runtime) if the factory cannot create an object
*/
T create();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import org.apache.commons.collections4.functors.ConstantFactory;
import org.apache.commons.collections4.functors.ExceptionFactory;
import org.apache.commons.collections4.functors.InstantiateFactory;
import org.apache.commons.collections4.functors.PrototypeFactory;
/**
* {@code FactoryUtils} provides reference implementations and utilities
* for the Factory functor interface. The supplied factories are:
* <ul>
* <li>Prototype - clones a specified object
* <li>Instantiate - creates objects using reflection
* <li>Constant - always returns the same object
* <li>Null - always returns null
* <li>Exception - always throws an exception
* </ul>
* <p>
* Since v4.1 only factories which are considered to be safe are
* Serializable. Factories considered to be unsafe for serialization are:
* <ul>
* <li>Prototype
* <li>Instantiate
* </ul>
*
* @since 3.0
*/
public class FactoryUtils {
/**
* Don't allow instances.
*/
private FactoryUtils() {}
/**
* Gets a Factory that always throws an exception.
* This could be useful during testing as a placeholder.
*
* @see org.apache.commons.collections4.functors.ExceptionFactory
*
* @param <T> the type that the factory creates
* @return the factory
*/
public static <T> Factory<T> exceptionFactory() {
return ExceptionFactory.<T>exceptionFactory();
}
/**
* Gets a Factory that will return null each time the factory is used.
* This could be useful during testing as a placeholder.
*
* @see org.apache.commons.collections4.functors.ConstantFactory
* @param <T> the "type" of null object the factory should return.
* @return the factory
*/
public static <T> Factory<T> nullFactory() {
return ConstantFactory.<T>constantFactory(null);
}
/**
* Creates a Factory that will return the same object each time the factory
* is used. No check is made that the object is immutable. In general, only
* immutable objects should use the constant factory. Mutable objects should
* use the prototype factory.
*
* @see org.apache.commons.collections4.functors.ConstantFactory
*
* @param <T> the type that the factory creates
* @param constantToReturn the constant object to return each time in the factory
* @return the {@code constant} factory.
*/
public static <T> Factory<T> constantFactory(final T constantToReturn) {
return ConstantFactory.constantFactory(constantToReturn);
}
/**
* Creates a Factory that will return a clone of the same prototype object
* each time the factory is used. The prototype will be cloned using one of these
* techniques (in order):
*
* <ul>
* <li>public clone method</li>
* <li>public copy constructor</li>
* <li>serialization clone</li>
* </ul>
*
* @see org.apache.commons.collections4.functors.PrototypeFactory
*
* @param <T> the type that the factory creates
* @param prototype the object to clone each time in the factory
* @return the {@code prototype} factory, or a {@link ConstantFactory#NULL_INSTANCE} if
* the {@code prototype} is {@code null}
* @throws IllegalArgumentException if the prototype cannot be cloned
*/
public static <T> Factory<T> prototypeFactory(final T prototype) {
return PrototypeFactory.<T>prototypeFactory(prototype);
}
/**
* Creates a Factory that can create objects of a specific type using
* a no-args constructor.
*
* @see org.apache.commons.collections4.functors.InstantiateFactory
*
* @param <T> the type that the factory creates
* @param classToInstantiate the Class to instantiate each time in the factory
* @return the {@code reflection} factory
* @throws NullPointerException if the classToInstantiate is null
*/
public static <T> Factory<T> instantiateFactory(final Class<T> classToInstantiate) {
return InstantiateFactory.instantiateFactory(classToInstantiate, null, null);
}
/**
* Creates a Factory that can create objects of a specific type using
* the arguments specified to this method.
*
* @see org.apache.commons.collections4.functors.InstantiateFactory
*
* @param <T> the type that the factory creates
* @param classToInstantiate the Class to instantiate each time in the factory
* @param paramTypes parameter types for the constructor, can be null
* @param args the arguments to pass to the constructor, can be null
* @return the {@code reflection} factory
* @throws NullPointerException if the classToInstantiate is null
* @throws IllegalArgumentException if the paramTypes and args don't match
* @throws IllegalArgumentException if the constructor doesn't exist
*/
public static <T> Factory<T> instantiateFactory(final Class<T> classToInstantiate, final Class<?>[] paramTypes,
final Object[] args) {
return InstantiateFactory.instantiateFactory(classToInstantiate, paramTypes, args);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Runtime exception thrown from functors.
* If required, a root cause error can be wrapped within this one.
*
* @since 3.0
*/
public class FunctorException extends RuntimeException {
/** Serialization version */
private static final long serialVersionUID = -4704772662059351193L;
/**
* Constructs a new {@code FunctorException} without specified
* detail message.
*/
public FunctorException() {
}
/**
* Constructs a new {@code FunctorException} with specified
* detail message.
*
* @param msg the error message.
*/
public FunctorException(final String msg) {
super(msg);
}
/**
* Constructs a new {@code FunctorException} with specified
* nested {@code Throwable} root cause.
*
* @param rootCause the exception or error that caused this exception
* to be thrown.
*/
public FunctorException(final Throwable rootCause) {
super(rootCause);
}
/**
* Constructs a new {@code FunctorException} with specified
* detail message and nested {@code Throwable} root cause.
*
* @param msg the error message.
* @param rootCause the exception or error that caused this exception
* to be thrown.
*/
public FunctorException(final String msg, final Throwable rootCause) {
super(msg, rootCause);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Collection;
import java.util.Set;
/**
* The "read" subset of the {@link java.util.Map} interface.
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
*
* @since 4.0
* @see Put
*/
public interface Get<K, V> {
/**
* @param key key whose presence in this map is to be tested
* @return {@code true} if this map contains a mapping for the specified
* key
* @see java.util.Map#containsKey(Object)
*/
boolean containsKey(Object key);
/**
* @param value value whose presence in this map is to be tested
* @return {@code true} if this map maps one or more keys to the
* specified value
* @see java.util.Map#containsValue(Object)
*/
boolean containsValue(Object value);
/**
* @return a set view of the mappings contained in this map
* @see java.util.Map#entrySet()
*/
Set<java.util.Map.Entry<K, V>> entrySet();
/**
* @param key the key whose associated value is to be returned
* @return the value to which the specified key is mapped, or
* {@code null} if this map contains no mapping for the key
* @see java.util.Map#get(Object)
*/
V get(Object key);
/**
* @param key key whose mapping is to be removed from the map
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}.
* @see java.util.Map#remove(Object)
*/
V remove(Object key);
/**
* @return {@code true} if this map contains no key-value mappings
* @see java.util.Map#isEmpty()
*/
boolean isEmpty();
/**
* @return a set view of the keys contained in this map
* @see java.util.Map#keySet()
*/
Set<K> keySet();
/**
* @return the number of key-value mappings in this map
* @see java.util.Map#size()
*/
int size();
/**
* @return a collection view of the values contained in this map
* @see java.util.Map#values()
*/
Collection<V> values();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* The "read" subset of the {@link java.util.Map} interface.
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
*
* @since 4.0
* @see Put
*/
public interface IterableGet<K, V> extends Get<K, V> {
/**
* Obtains a {@code MapIterator} over the map.
* <p>
* A map iterator is an efficient way of iterating over maps.
* There is no need to access the entry set or use Map Entry objects.
* <pre>
* IterableMap&lt;String,Integer&gt; map = new HashedMap&lt;String,Integer&gt;();
* MapIterator&lt;String,Integer&gt; it = map.mapIterator();
* while (it.hasNext()) {
* String key = it.next();
* Integer value = it.getValue();
* it.setValue(value + 1);
* }
* </pre>
*
* @return a map iterator
*/
MapIterator<K, V> mapIterator();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Map;
/**
* Defines a map that can be iterated directly without needing to create an entry set.
* <p>
* A map iterator is an efficient way of iterating over maps.
* There is no need to access the entry set or use Map Entry objects.
* </p>
* <pre>
* IterableMap&lt;String,Integer&gt; map = new HashedMap&lt;String,Integer&gt;();
* MapIterator&lt;String,Integer&gt; it = map.mapIterator();
* while (it.hasNext()) {
* String key = it.next();
* Integer value = it.getValue();
* it.setValue(value + 1);
* }
* </pre>
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
*
* @since 3.0
*/
public interface IterableMap<K, V> extends Map<K, V>, Put<K, V>, IterableGet<K, V> {
// empty
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.SortedMap;
/**
* {@link SortedMap} + {@link OrderedMap}.
*
* @param <K> the type of the keys in the map
* @param <V> the type of the values in the map
*
* @since 4.0
*/
public interface IterableSortedMap<K, V> extends SortedMap<K, V>, OrderedMap<K, V> {
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a simple key value pair.
* <p>
* A Map Entry has considerable additional semantics over and above a simple
* key-value pair. This interface defines the minimum key value, with just the
* two get methods.
* </p>
*
* @param <K> the type of the key
* @param <V> the type of the value
* @since 3.0
*/
public interface KeyValue<K, V> {
/**
* Gets the key from the pair.
*
* @return the key
*/
K getKey();
/**
* Gets the value from the pair.
*
* @return the value
*/
V getValue();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.List;
/**
* Defines a map that holds a list of values against each key.
* <p>
* A {@code ListValuedMap} is a Map with slightly different semantics:
* </p>
* <ul>
* <li>Putting a value into the map will add the value to a {@link List} at that key.</li>
* <li>Getting a value will return a {@link List}, holding all the values put to that key.</li>
* </ul>
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
* @since 4.1
*/
public interface ListValuedMap<K, V> extends MultiValuedMap<K, V> {
/**
* Gets the list of values associated with the specified key.
* <p>
* This method will return an <b>empty</b> list if
* {@link #containsKey(Object)} returns {@code false}. Changes to the
* returned list will update the underlying {@code ListValuedMap} and
* vice-versa.
*
* @param key the key to retrieve
* @return the {@code List} of values, implementations should return an
* empty {@code List} for no mapping
* @throws NullPointerException if the key is null and null keys are invalid
*/
@Override
List<V> get(K key);
/**
* Removes all values associated with the specified key.
* <p>
* The returned list <i>may</i> be modifiable, but updates will not be
* propagated to this list-valued map. In case no mapping was stored for the
* specified key, an empty, unmodifiable list will be returned.
*
* @param key the key to remove values from
* @return the {@code List} of values removed, implementations
* typically return an empty, unmodifiable {@code List} for no mapping found
* @throws UnsupportedOperationException if the map is unmodifiable
* @throws NullPointerException if the key is null and null keys are invalid
*/
@Override
List<V> remove(Object key);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Iterator;
/**
* Defines an iterator that operates over a {@code Map}.
* <p>
* This iterator is a special version designed for maps. It can be more
* efficient to use this rather than an entry set iterator where the option
* is available, and it is certainly more convenient.
* </p>
* <p>
* A map that provides this interface may not hold the data internally using
* Map Entry objects, thus this interface can avoid lots of object creation.
* </p>
* <p>
* In use, this iterator iterates through the keys in the map. After each call
* to {@code next()}, the {@code getValue()} method provides direct
* access to the value. The value can also be set using {@code setValue()}.
* </p>
* <pre>{@code
* MapIterator<String,Integer> it = map.mapIterator();
* while (it.hasNext()) {
* String key = it.next();
* Integer value = it.getValue();
* it.setValue(value + 1);
* }
* }</pre>
*
* @param <K> the type of the keys in the map
* @param <V> the type of the values in the map
* @since 3.0
*/
public interface MapIterator<K, V> extends Iterator<K> {
/**
* Checks to see if there are more entries still to be iterated.
*
* @return {@code true} if the iterator has more elements
*/
@Override
boolean hasNext();
/**
* Gets the next <em>key</em> from the {@code Map}.
*
* @return the next key in the iteration
* @throws java.util.NoSuchElementException if the iteration is finished
*/
@Override
K next();
/**
* Gets the current key, which is the key returned by the last call
* to {@code next()}.
*
* @return the current key
* @throws IllegalStateException if {@code next()} has not yet been called
*/
K getKey();
/**
* Gets the current value, which is the value associated with the last key
* returned by {@code next()}.
*
* @return the current value
* @throws IllegalStateException if {@code next()} has not yet been called
*/
V getValue();
/**
* Removes the last returned key from the underlying {@code Map} (optional operation).
* <p>
* This method can be called once per call to {@code next()}.
*
* @throws UnsupportedOperationException if remove is not supported by the map
* @throws IllegalStateException if {@code next()} has not yet been called
* @throws IllegalStateException if {@code remove()} has already been called
* since the last call to {@code next()}
*/
@Override
void remove();
/**
* Sets the value associated with the current key (optional operation).
*
* @param value the new value
* @return the previous value
* @throws UnsupportedOperationException if setValue is not supported by the map
* @throws IllegalStateException if {@code next()} has not yet been called
* @throws IllegalStateException if {@code remove()} has been called since the
* last call to {@code next()}
*/
V setValue(V value);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Collection;
/**
* Defines a map that holds a collection of values against each key.
* <p>
* A {@code MultiMap} is a Map with slightly different semantics.
* Putting a value into the map will add the value to a Collection at that key.
* Getting a value will return a Collection, holding all the values put to that key.
* </p>
* <p>
* For example:
* </p>
* <pre>
* MultiMap mhm = new MultiValueMap();
* mhm.put(key, "A");
* mhm.put(key, "B");
* mhm.put(key, "C");
* Collection coll = (Collection) mhm.get(key);</pre>
* <p>
* {@code coll} will be a collection containing "A", "B", "C".
* </p>
* <p>
* NOTE: Additional methods were added to this interface in Commons Collections 3.1.
* These were added solely for documentation purposes and do not change the interface
* as they were defined in the superinterface {@code Map} anyway.
* </p>
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
*
* @since 2.0
* @deprecated since 4.1, use {@link MultiValuedMap} instead
*/
@Deprecated
public interface MultiMap<K, V> extends IterableMap<K, Object> {
/**
* Removes a specific value from map.
* <p>
* The item is removed from the collection mapped to the specified key.
* Other values attached to that key are unaffected.
* <p>
* If the last value for a key is removed, implementations typically
* return {@code null} from a subsequent {@code get(Object)}, however
* they may choose to return an empty collection.
*
* @param key the key to remove from
* @param item the item to remove
* @return {@code true} if the mapping was removed, {@code false} otherwise
* @throws UnsupportedOperationException if the map is unmodifiable
* @throws ClassCastException if the key or value is of an invalid type
* @throws NullPointerException if the key or value is null and null is invalid
* @since 4.0 (signature in previous releases: V remove(K, V))
*/
boolean removeMapping(K key, V item);
/**
* Gets the number of keys in this map.
* <p>
* Implementations typically return only the count of keys in the map
* This cannot be mandated due to backwards compatibility of this interface.
*
* @return the number of key-collection mappings in this map
*/
@Override
int size();
/**
* Gets the collection of values associated with the specified key.
* <p>
* The returned value will implement {@code Collection}. Implementations
* are free to declare that they return {@code Collection} subclasses
* such as {@code List} or {@code Set}.
* <p>
* Implementations typically return {@code null} if no values have
* been mapped to the key, however the implementation may choose to
* return an empty collection.
* <p>
* Implementations may choose to return a clone of the internal collection.
*
* @param key the key to retrieve
* @return the {@code Collection} of values, implementations should
* return {@code null} for no mapping, but may return an empty collection
* @throws ClassCastException if the key is of an invalid type
* @throws NullPointerException if the key is null and null keys are invalid
*/
@Override
Object get(Object key); // Cannot use get(K key) as that does not properly implement Map#get
/**
* Checks whether the map contains the value specified.
* <p>
* Implementations typically check all collections against all keys for the value.
* This cannot be mandated due to backwards compatibility of this interface.
*
* @param value the value to search for
* @return true if the map contains the value
* @throws ClassCastException if the value is of an invalid type
* @throws NullPointerException if the value is null and null value are invalid
*/
@Override
boolean containsValue(Object value);
/**
* Adds the value to the collection associated with the specified key.
* <p>
* Unlike a normal {@code Map} the previous value is not replaced.
* Instead the new value is added to the collection stored against the key.
* The collection may be a {@code List}, {@code Set} or other
* collection dependent on implementation.
*
* @param key the key to store against
* @param value the value to add to the collection at the key
* @return typically the value added if the map changed and null if the map did not change
* @throws UnsupportedOperationException if the map is unmodifiable
* @throws ClassCastException if the key or value is of an invalid type
* @throws NullPointerException if the key or value is null and null is invalid
* @throws IllegalArgumentException if the key or value is invalid
*/
@Override
Object put(K key, Object value);
/**
* Removes all values associated with the specified key.
* <p>
* Implementations typically return {@code null} from a subsequent
* {@code get(Object)}, however they may choose to return an empty collection.
*
* @param key the key to remove values from
* @return the {@code Collection} of values removed, implementations should
* return {@code null} for no mapping found, but may return an empty collection
* @throws UnsupportedOperationException if the map is unmodifiable
* @throws ClassCastException if the key is of an invalid type
* @throws NullPointerException if the key is null and null keys are invalid
*/
@Override
Object remove(Object key); // Cannot use remove(K key) as that does not properly implement Map#remove
/**
* Gets a collection containing all the values in the map.
* <p>
* Implementations typically return a collection containing the combination
* of values from all keys.
* This cannot be mandated due to backwards compatibility of this interface.
*
* @return a collection view of the values contained in this map
*/
@Override
Collection<Object> values();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.bag.HashBag;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
import org.apache.commons.collections4.multimap.TransformedMultiValuedMap;
import org.apache.commons.collections4.multimap.UnmodifiableMultiValuedMap;
/**
* Provides utility methods and decorators for {@link MultiValuedMap} instances.
* <p>
* It contains various type safe and null safe methods. Additionally, it provides
* the following decorators:
* </p>
* <ul>
* <li>{@link #unmodifiableMultiValuedMap(MultiValuedMap)}</li>
* <li>{@link #transformedMultiValuedMap(MultiValuedMap, Transformer, Transformer)}</li>
* </ul>
*
* @since 4.1
*/
public class MultiMapUtils {
/**
* Don't allow instances.
*/
private MultiMapUtils() {}
/**
* An empty {@link UnmodifiableMultiValuedMap}.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static final MultiValuedMap EMPTY_MULTI_VALUED_MAP =
UnmodifiableMultiValuedMap.unmodifiableMultiValuedMap(new ArrayListValuedHashMap(0, 0));
/**
* Returns immutable EMPTY_MULTI_VALUED_MAP with generic type safety.
*
* @param <K> the type of key in the map
* @param <V> the type of value in the map
* @return immutable and empty {@code MultiValuedMap}
*/
@SuppressWarnings("unchecked")
public static <K, V> MultiValuedMap<K, V> emptyMultiValuedMap() {
return EMPTY_MULTI_VALUED_MAP;
}
// Null safe methods
/**
* Returns an immutable empty {@code MultiValuedMap} if the argument is
* {@code null}, or the argument itself otherwise.
*
* @param <K> the type of key in the map
* @param <V> the type of value in the map
* @param map the map, may be null
* @return an empty {@link MultiValuedMap} if the argument is null
*/
@SuppressWarnings("unchecked")
public static <K, V> MultiValuedMap<K, V> emptyIfNull(final MultiValuedMap<K, V> map) {
return map == null ? EMPTY_MULTI_VALUED_MAP : map;
}
/**
* Null-safe check if the specified {@code MultiValuedMap} is empty.
* <p>
* If the provided map is null, returns true.
*
* @param map the map to check, may be null
* @return true if the map is empty or null
*/
public static boolean isEmpty(final MultiValuedMap<?, ?> map) {
return map == null || map.isEmpty();
}
/**
* Gets a Collection from {@code MultiValuedMap} in a null-safe manner.
*
* @param <K> the key type
* @param <V> the value type
* @param map the {@link MultiValuedMap} to use
* @param key the key to look up
* @return the Collection in the {@link MultiValuedMap}, or null if input map is null
*/
public static <K, V> Collection<V> getCollection(final MultiValuedMap<K, V> map, final K key) {
if (map != null) {
return map.get(key);
}
return null;
}
// TODO: review the getValuesAsXXX methods - depending on the actual MultiValuedMap type, changes
// to the returned collection might update the backing map. This should be clarified and/or prevented.
/**
* Gets a List from {@code MultiValuedMap} in a null-safe manner.
*
* @param <K> the key type
* @param <V> the value type
* @param map the {@link MultiValuedMap} to use
* @param key the key to look up
* @return the Collection in the {@link MultiValuedMap} as List, or null if input map is null
*/
public static <K, V> List<V> getValuesAsList(final MultiValuedMap<K, V> map, final K key) {
if (map != null) {
final Collection<V> col = map.get(key);
if (col instanceof List) {
return (List<V>) col;
}
return new ArrayList<>(col);
}
return null;
}
/**
* Gets a Set from {@code MultiValuedMap} in a null-safe manner.
*
* @param <K> the key type
* @param <V> the value type
* @param map the {@link MultiValuedMap} to use
* @param key the key to look up
* @return the Collection in the {@link MultiValuedMap} as Set, or null if input map is null
*/
public static <K, V> Set<V> getValuesAsSet(final MultiValuedMap<K, V> map, final K key) {
if (map != null) {
final Collection<V> col = map.get(key);
if (col instanceof Set) {
return (Set<V>) col;
}
return new HashSet<>(col);
}
return null;
}
/**
* Gets a Bag from {@code MultiValuedMap} in a null-safe manner.
*
* @param <K> the key type
* @param <V> the value type
* @param map the {@link MultiValuedMap} to use
* @param key the key to look up
* @return the Collection in the {@link MultiValuedMap} as Bag, or null if input map is null
*/
public static <K, V> Bag<V> getValuesAsBag(final MultiValuedMap<K, V> map, final K key) {
if (map != null) {
final Collection<V> col = map.get(key);
if (col instanceof Bag) {
return (Bag<V>) col;
}
return new HashBag<>(col);
}
return null;
}
/**
* Creates a {@link ListValuedMap} with an {@link java.util.ArrayList ArrayList} as
* collection class to store the values mapped to a key.
*
* @param <K> the key type
* @param <V> the value type
* @return a new {@code ListValuedMap}
*/
public static <K, V> ListValuedMap<K, V> newListValuedHashMap() {
return new ArrayListValuedHashMap<>();
}
/**
* Creates a {@link SetValuedMap} with an {@link java.util.HashSet HashSet} as
* collection class to store the values mapped to a key.
*
* @param <K> the key type
* @param <V> the value type
* @return a new {@link SetValuedMap}
*/
public static <K, V> SetValuedMap<K, V> newSetValuedHashMap() {
return new HashSetValuedHashMap<>();
}
/**
* Returns an {@code UnmodifiableMultiValuedMap} backed by the given
* map.
*
* @param <K> the key type
* @param <V> the value type
* @param map the {@link MultiValuedMap} to decorate, must not be null
* @return an unmodifiable {@link MultiValuedMap} backed by the provided map
* @throws NullPointerException if map is null
*/
public static <K, V> MultiValuedMap<K, V> unmodifiableMultiValuedMap(
final MultiValuedMap<? extends K, ? extends V> map) {
return UnmodifiableMultiValuedMap.<K, V>unmodifiableMultiValuedMap(map);
}
/**
* Returns a {@code TransformedMultiValuedMap} backed by the given map.
* <p>
* This method returns a new {@code MultiValuedMap} (decorating the
* specified map) that will transform any new entries added to it. Existing
* entries in the specified map will not be transformed. If you want that
* behavior, see {@link TransformedMultiValuedMap#transformedMap}.
* <p>
* Each object is passed through the transformers as it is added to the Map.
* It is important not to use the original map after invoking this method,
* as it is a back door for adding untransformed objects.
* <p>
* If there are any elements already in the map being decorated, they are
* NOT transformed.
*
* @param <K> the key type
* @param <V> the value type
* @param map the {@link MultiValuedMap} to transform, must not be null, typically empty
* @param keyTransformer the transformer for the map keys, null means no transformation
* @param valueTransformer the transformer for the map values, null means no transformation
* @return a transformed {@code MultiValuedMap} backed by the given map
* @throws NullPointerException if map is null
*/
public static <K, V> MultiValuedMap<K, V> transformedMultiValuedMap(final MultiValuedMap<K, V> map,
final Transformer<? super K, ? extends K> keyTransformer,
final Transformer<? super V, ? extends V> valueTransformer) {
return TransformedMultiValuedMap.transformingMap(map, keyTransformer, valueTransformer);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* Defines a collection that counts the number of times an object appears in
* the collection.
* <p>
* Suppose you have a MultiSet that contains {@code {a, a, b, c}}.
* Calling {@link #getCount(Object)} on {@code a} would return 2, while
* calling {@link #uniqueSet()} would return {@code {a, b, c}}.
* </p>
*
* @param <E> the type held in the multiset
* @since 4.1
*/
public interface MultiSet<E> extends Collection<E> {
/**
* Returns the number of occurrences of the given object currently
* in the MultiSet. If the object does not exist in the multiset,
* return 0.
*
* @param object the object to search for
* @return the number of occurrences of the object, zero if not found
*/
int getCount(Object object);
/**
* Sets the number of occurrences of the specified object in the MultiSet
* to the given count.
* <p>
* If the provided count is zero, the object will be removed from the
* {@link #uniqueSet()}.
*
* @param object the object to update
* @param count the number of occurrences of the object
* @return the number of occurrences of the object before this operation, zero
* if the object was not contained in the multiset
* @throws IllegalArgumentException if count is negative
*/
int setCount(E object, int count);
/**
* Adds one copy of the specified object to the MultiSet.
* <p>
* If the object is already in the {@link #uniqueSet()} then increment its
* count as reported by {@link #getCount(Object)}. Otherwise add it to the
* {@link #uniqueSet()} and report its count as 1.
*
* @param object the object to add
* @return {@code true} always, as the size of the MultiSet is increased
* in any case
*/
@Override
boolean add(E object);
/**
* Adds a number of occurrences of the specified object to the MultiSet.
* <p>
* If the object is already in the {@link #uniqueSet()} then increment its
* count as reported by {@link #getCount(Object)}. Otherwise add it to the
* {@link #uniqueSet()} and report its count as {@code occurrences}.
*
* @param object the object to add
* @param occurrences the number of occurrences to add, may be zero,
* in which case no change is made to the multiset
* @return the number of occurrences of the object in the multiset before
* this operation; possibly zero
* @throws IllegalArgumentException if occurrences is negative
*/
int add(E object, int occurrences);
/**
* Removes one occurrence of the given object from the MultiSet.
* <p>
* If the number of occurrences after this operations is reduced
* to zero, the object will be removed from the {@link #uniqueSet()}.
*
* @param object the object to remove
* @return {@code true} if this call changed the collection
*/
@Override
boolean remove(Object object);
/**
* Removes a number of occurrences of the specified object from the MultiSet.
* <p>
* If the number of occurrences to remove is greater than the actual number of
* occurrences in the multiset, the object will be removed from the multiset.
*
* @param object the object to remove
* @param occurrences the number of occurrences to remove, may be zero,
* in which case no change is made to the multiset
* @return the number of occurrences of the object in the multiset
* before the operation; possibly zero
* @throws IllegalArgumentException if occurrences is negative
*/
int remove(Object object, int occurrences);
/**
* Returns a {@link Set} of unique elements in the MultiSet.
* <p>
* Uniqueness constraints are the same as those in {@link java.util.Set}.
* <p>
* The returned set is backed by this multiset, so any change to either
* is immediately reflected in the other. Only removal operations are
* supported, in which case all occurrences of the element are removed
* from the backing multiset.
*
* @return the Set of unique MultiSet elements
*/
Set<E> uniqueSet();
/**
* Returns a {@link Set} of all entries contained in the MultiSet.
* <p>
* The returned set is backed by this multiset, so any change to either
* is immediately reflected in the other.
*
* @return the Set of MultiSet entries
*/
Set<Entry<E>> entrySet();
/**
* Returns an {@link Iterator} over the entire set of members,
* including copies due to cardinality. This iterator is fail-fast
* and will not tolerate concurrent modifications.
*
* @return iterator over all elements in the MultiSet
*/
@Override
Iterator<E> iterator();
/**
* Returns the total number of items in the MultiSet.
*
* @return the total size of the multiset
*/
@Override
int size();
/**
* Returns {@code true} if the MultiSet contains at least one
* occurrence for each element contained in the given collection.
*
* @param coll the collection to check against
* @return {@code true} if the MultiSet contains all the collection
*/
@Override
boolean containsAll(Collection<?> coll);
/**
* Remove all occurrences of all elements from this MultiSet represented
* in the given collection.
*
* @param coll the collection of elements to remove
* @return {@code true} if this call changed the multiset
*/
@Override
boolean removeAll(Collection<?> coll);
/**
* Remove any elements of this MultiSet that are not contained in the
* given collection.
*
* @param coll the collection of elements to retain
* @return {@code true} if this call changed the multiset
*/
@Override
boolean retainAll(Collection<?> coll);
/**
* Compares this MultiSet to another object.
* <p>
* This MultiSet equals another object if it is also a MultiSet
* that contains the same number of occurrences of the same elements.
*
* @param obj the object to compare to
* @return true if equal
*/
@Override
boolean equals(Object obj);
/**
* Gets a hash code for the MultiSet compatible with the definition of equals.
* The hash code is defined as the sum total of a hash code for each element.
* The per element hash code is defined as
* {@code (e==null ? 0 : e.hashCode()) ^ noOccurrences)}.
*
* @return the hash code of the MultiSet
*/
@Override
int hashCode();
/**
* An unmodifiable entry for an element and its occurrence as contained in a MultiSet.
* <p>
* The {@link MultiSet#entrySet()} method returns a view of the multiset whose elements
* implements this interface.
*
* @param <E> the element type
*/
interface Entry<E> {
/**
* Returns the element corresponding to this entry.
*
* @return the element corresponding to this entry
*/
E getElement();
/**
* Returns the number of occurrences for the element of this entry.
*
* @return the number of occurrences of the element
*/
int getCount();
/**
* Compares the specified object with this entry for equality.
* Returns true if the given object is also a multiset entry
* and the two entries represent the same element with the same
* number of occurrences.
* <p>
* More formally, two entries {@code e1} and {@code e2} represent
* the same mapping if
* <pre>
* (e1.getElement()==null ? e2.getElement()==null
* : e1.getElement().equals(e2.getElement())) &amp;&amp;
* (e1.getCount()==e2.getCount())
* </pre>
*
* @param o object to be compared for equality with this multiset entry
* @return true if the specified object is equal to this multiset entry
*/
@Override
boolean equals(Object o);
/**
* Returns the hash code value for this multiset entry.
* <p>
* The hash code of a multiset entry {@code e} is defined to be:
* <pre>
* (e==null ? 0 : e.hashCode()) ^ noOccurrences)
* </pre>
*
* @return the hash code value for this multiset entry
*/
@Override
int hashCode();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import org.apache.commons.collections4.multiset.HashMultiSet;
import org.apache.commons.collections4.multiset.PredicatedMultiSet;
import org.apache.commons.collections4.multiset.SynchronizedMultiSet;
import org.apache.commons.collections4.multiset.UnmodifiableMultiSet;
/**
* Provides utility methods and decorators for {@link MultiSet} instances.
*
* @since 4.1
*/
public class MultiSetUtils {
/**
* An empty unmodifiable multiset.
*/
@SuppressWarnings("rawtypes") // OK, empty multiset is compatible with any type
public static final MultiSet EMPTY_MULTISET =
UnmodifiableMultiSet.unmodifiableMultiSet(new HashMultiSet<>());
/**
* Don't allow instances.
*/
private MultiSetUtils() {}
/**
* Returns a synchronized (thread-safe) multiset backed by the given multiset.
* In order to guarantee serial access, it is critical that all access to the
* backing multiset is accomplished through the returned multiset.
* <p>
* It is imperative that the user manually synchronize on the returned multiset
* when iterating over it:
*
* <pre>
* MultiSet multiset = MultiSetUtils.synchronizedMultiSet(new HashMultiSet());
* ...
* synchronized(multiset) {
* Iterator i = multiset.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
* }
* }
* </pre>
*
* Failure to follow this advice may result in non-deterministic behavior.
*
* @param <E> the element type
* @param multiset the multiset to synchronize, must not be null
* @return a synchronized multiset backed by that multiset
* @throws NullPointerException if the MultiSet is null
*/
public static <E> MultiSet<E> synchronizedMultiSet(final MultiSet<E> multiset) {
return SynchronizedMultiSet.synchronizedMultiSet(multiset);
}
/**
* Returns an unmodifiable view of the given multiset. Any modification attempts
* to the returned multiset will raise an {@link UnsupportedOperationException}.
*
* @param <E> the element type
* @param multiset the multiset whose unmodifiable view is to be returned, must not be null
* @return an unmodifiable view of that multiset
* @throws NullPointerException if the MultiSet is null
*/
public static <E> MultiSet<E> unmodifiableMultiSet(final MultiSet<? extends E> multiset) {
return UnmodifiableMultiSet.unmodifiableMultiSet(multiset);
}
/**
* Returns a predicated (validating) multiset backed by the given multiset.
* <p>
* Only objects that pass the test in the given predicate can be added to
* the multiset. Trying to add an invalid object results in an
* IllegalArgumentException. It is important not to use the original multiset
* after invoking this method, as it is a backdoor for adding invalid
* objects.
*
* @param <E> the element type
* @param multiset the multiset to predicate, must not be null
* @param predicate the predicate for the multiset, must not be null
* @return a predicated multiset backed by the given multiset
* @throws NullPointerException if the MultiSet or Predicate is null
*/
public static <E> MultiSet<E> predicatedMultiSet(final MultiSet<E> multiset,
final Predicate<? super E> predicate) {
return PredicatedMultiSet.predicatedMultiSet(multiset, predicate);
}
/**
* Get an empty {@code MultiSet}.
*
* @param <E> the element type
* @return an empty MultiSet
*/
@SuppressWarnings("unchecked") // OK, empty multiset is compatible with any type
public static <E> MultiSet<E> emptyMultiSet() {
return EMPTY_MULTISET;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a map that allows bidirectional lookup between key and values
* and retains and provides access to an ordering.
* <p>
* Implementations should allow a value to be looked up from a key and
* a key to be looked up from a value with equal performance.
* </p>
*
* @param <K> the type of the keys in the map
* @param <V> the type of the values in the map
*
* @since 3.0
*/
public interface OrderedBidiMap<K, V> extends BidiMap<K, V>, OrderedMap<K, V> {
/**
* Gets a view of this map where the keys and values are reversed.
* <p>
* Changes to one map will be visible in the other and vice versa.
* This enables both directions of the map to be accessed equally.
* <p>
* Implementations should seek to avoid creating a new object every time this
* method is called. See {@code AbstractMap.values()} etc. Calling this
* method on the inverse map should return the original.
* <p>
* Implementations must return an {@code OrderedBidiMap} instance,
* usually by forwarding to {@code inverseOrderedBidiMap()}.
*
* @return an inverted bidirectional map
*/
@Override
OrderedBidiMap<V, K> inverseBidiMap();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Iterator;
/**
* Defines an iterator that operates over an ordered container. Subset of {@link java.util.ListIterator}.
* <p>
* This iterator allows both forward and reverse iteration through the container.
* </p>
*
* @param <E> the type of elements returned by this iterator.
* @since 3.0
*/
public interface OrderedIterator<E> extends Iterator<E> {
/**
* Checks to see if there is a previous element that can be iterated to.
*
* @return {@code true} if the iterator has a previous element
*/
boolean hasPrevious();
/**
* Gets the previous element from the container.
*
* @return the previous element in the iteration
* @throws java.util.NoSuchElementException if the iteration is finished
*/
E previous();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a map that maintains order and allows both forward and backward
* iteration through that order.
*
* @param <K> the type of the keys in the map
* @param <V> the type of the values in the map
*
* @since 3.0
*/
public interface OrderedMap<K, V> extends IterableMap<K, V> {
/**
* Obtains an {@code OrderedMapIterator} over the map.
* <p>
* A ordered map iterator is an efficient way of iterating over maps
* in both directions.
*
* @return a map iterator
*/
@Override
OrderedMapIterator<K, V> mapIterator();
/**
* Gets the first key currently in this map.
*
* @return the first key currently in this map
* @throws java.util.NoSuchElementException if this map is empty
*/
K firstKey();
/**
* Gets the last key currently in this map.
*
* @return the last key currently in this map
* @throws java.util.NoSuchElementException if this map is empty
*/
K lastKey();
/**
* Gets the next key after the one specified.
*
* @param key the key to search for next from
* @return the next key, null if no match or at end
*/
K nextKey(K key);
/**
* Gets the previous key before the one specified.
*
* @param key the key to search for previous from
* @return the previous key, null if no match or at start
*/
K previousKey(K key);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines an iterator that operates over an ordered {@code Map}.
* <p>
* This iterator allows both forward and reverse iteration through the map.
* </p>
*
* @param <K> the type of the keys in the map
* @param <V> the type of the values in the map
* @since 3.0
*/
public interface OrderedMapIterator<K, V> extends MapIterator<K, V>, OrderedIterator<K> {
/**
* Checks to see if there is a previous entry that can be iterated to.
*
* @return {@code true} if the iterator has a previous element
*/
@Override
boolean hasPrevious();
/**
* Gets the previous <em>key</em> from the {@code Map}.
*
* @return the previous key in the iteration
* @throws java.util.NoSuchElementException if the iteration is finished
*/
@Override
K previous();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a functor interface implemented by classes that perform a predicate
* test on an object.
* <p>
* A {@code Predicate} is the object equivalent of an {@code if} statement.
* It uses the input object to return a true or false value, and is often used in
* validation or filtering.
* </p>
* <p>
* Standard implementations of common predicates are provided by
* {@link PredicateUtils}. These include true, false, instanceof, equals, and,
* or, not, method invocation and null testing.
* </p>
*
* @param <T> the type that the predicate queries
*
* @since 1.0
*/
@FunctionalInterface
public interface Predicate<T> {
/**
* Use the specified parameter to perform a test that returns true or false.
*
* @param object the object to evaluate, should not be changed
* @return true or false
* @throws ClassCastException (runtime) if the input is the wrong class
* @throws IllegalArgumentException (runtime) if the input is invalid
* @throws FunctorException (runtime) if the predicate encounters a problem
*/
boolean evaluate(T object);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Map;
/**
* The "write" subset of the {@link Map} interface.
* <p>
* NOTE: in the original {@link Map} interface, {@link Map#put(Object, Object)} is known
* to have the same return type as {@link Map#get(Object)}, namely {@code V}. {@link Put}
* makes no assumptions in this regard (there is no association with, nor even knowledge
* of, a "reading" interface) and thus defines {@link #put(Object, Object)} as returning
* {@link Object}.
* </p>
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
*
* @since 4.0
* @see Get
*/
public interface Put<K, V> {
/**
* @see Map#clear()
*/
void clear();
/**
* Note that the return type is Object, rather than V as in the Map interface.
* See the class Javadoc for further info.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with {@code key},
* if the implementation supports {@code null} values.)
* @see Map#put(Object, Object)
*/
Object put(K key, V value);
/**
* @param t mappings to be stored in this map
* @see Map#putAll(Map)
*/
void putAll(Map<? extends K, ? extends V> t);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.LinkedList;
import java.util.Queue;
import org.apache.commons.collections4.queue.PredicatedQueue;
import org.apache.commons.collections4.queue.SynchronizedQueue;
import org.apache.commons.collections4.queue.TransformedQueue;
import org.apache.commons.collections4.queue.UnmodifiableQueue;
/**
* Provides utility methods and decorators for {@link Queue} instances.
*
* @since 4.0
*/
public class QueueUtils {
/**
* An empty unmodifiable queue.
*/
@SuppressWarnings("rawtypes") // OK, empty queue is compatible with any type
public static final Queue EMPTY_QUEUE = UnmodifiableQueue.unmodifiableQueue(new LinkedList<>());
/**
* Don't allow instances.
*/
private QueueUtils() {}
/**
* Returns a synchronized (thread-safe) queue backed by the given queue.
* In order to guarantee serial access, it is critical that all access to the
* backing queue is accomplished through the returned queue.
* <p>
* It is imperative that the user manually synchronize on the returned queue
* when iterating over it:
*
* <pre>
* Queue queue = QueueUtils.synchronizedQueue(new CircularFifoQueue());
* ...
* synchronized(queue) {
* Iterator i = queue.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
* }
* }
* </pre>
*
* Failure to follow this advice may result in non-deterministic behavior.
*
* @param <E> the element type
* @param queue the queue to synchronize, must not be null
* @return a synchronized queue backed by that queue
* @throws NullPointerException if the queue is null
* @since 4.2
*/
public static <E> Queue<E> synchronizedQueue(final Queue<E> queue) {
return SynchronizedQueue.synchronizedQueue(queue);
}
/**
* Returns an unmodifiable queue backed by the given queue.
*
* @param <E> the type of the elements in the queue
* @param queue the queue to make unmodifiable, must not be null
* @return an unmodifiable queue backed by that queue
* @throws NullPointerException if the queue is null
*/
public static <E> Queue<E> unmodifiableQueue(final Queue<? extends E> queue) {
return UnmodifiableQueue.unmodifiableQueue(queue);
}
/**
* Returns a predicated (validating) queue backed by the given queue.
* <p>
* Only objects that pass the test in the given predicate can be added to the queue.
* Trying to add an invalid object results in an IllegalArgumentException.
* It is important not to use the original queue after invoking this method,
* as it is a backdoor for adding invalid objects.
*
* @param <E> the type of the elements in the queue
* @param queue the queue to predicate, must not be null
* @param predicate the predicate used to evaluate new elements, must not be null
* @return a predicated queue
* @throws NullPointerException if the queue or predicate is null
*/
public static <E> Queue<E> predicatedQueue(final Queue<E> queue, final Predicate<? super E> predicate) {
return PredicatedQueue.predicatedQueue(queue, predicate);
}
/**
* Returns a transformed queue backed by the given queue.
* <p>
* Each object is passed through the transformer as it is added to the
* Queue. It is important not to use the original queue after invoking this
* method, as it is a backdoor for adding untransformed objects.
* <p>
* Existing entries in the specified queue will not be transformed.
* If you want that behavior, see {@link TransformedQueue#transformedQueue}.
*
* @param <E> the type of the elements in the queue
* @param queue the queue to predicate, must not be null
* @param transformer the transformer for the queue, must not be null
* @return a transformed queue backed by the given queue
* @throws NullPointerException if the queue or transformer is null
*/
public static <E> Queue<E> transformingQueue(final Queue<E> queue,
final Transformer<? super E, ? extends E> transformer) {
return TransformedQueue.transformingQueue(queue, transformer);
}
/**
* Get an empty {@code Queue}.
*
* @param <E> the type of the elements in the queue
* @return an empty {@link Queue}
*/
@SuppressWarnings("unchecked") // OK, empty queue is compatible with any type
public static <E> Queue<E> emptyQueue() {
return EMPTY_QUEUE;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Iterator;
/**
* Defines an iterator that can be reset back to an initial state.
* <p>
* This interface allows an iterator to be repeatedly reused.
* </p>
*
* @param <E> the type of elements returned by this iterator.
* @since 3.0
*/
public interface ResettableIterator<E> extends Iterator<E> {
/**
* Resets the iterator back to the position at which the iterator
* was created.
*/
void reset();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.ListIterator;
/**
* Defines a list iterator that can be reset back to an initial state.
* <p>
* This interface allows an iterator to be repeatedly reused.
* </p>
*
* @param <E> the type of elements returned by this iterator.
* @since 3.0
*/
public interface ResettableListIterator<E> extends ListIterator<E>, ResettableIterator<E>, OrderedIterator<E> {
// empty
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Set;
/**
* Defines a map that holds a set of values against each key.
* <p>
* A {@code SetValuedMap} is a Map with slightly different semantics:
* </p>
* <ul>
* <li>Putting a value into the map will add the value to a {@link Set} at that key.</li>
* <li>Getting a value will return a {@link Set}, holding all the values put to that key.</li>
* </ul>
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
* @since 4.1
*/
public interface SetValuedMap<K, V> extends MultiValuedMap<K, V> {
/**
* Gets the set of values associated with the specified key.
* <p>
* Implementations typically return an empty {@code Set} if no values
* have been mapped to the key.
* <p>
*
* @param key the key to retrieve
* @return the {@code Set} of values, implementations should return an
* empty {@code Set} for no mapping
* @throws NullPointerException if the key is null and null keys are invalid
*/
@Override
Set<V> get(K key);
/**
* Removes all values associated with the specified key.
* <p>
* The returned set <i>may</i> be modifiable, but updates will not be
* propagated to this set-valued map. In case no mapping was stored for the
* specified key, an empty, unmodifiable set will be returned.
*
* @param key the key to remove values from
* @return the {@code Set} of values removed, implementations should
* return null for no mapping found, but may return an empty collection
* @throws UnsupportedOperationException if the map is unmodifiable
* @throws NullPointerException if the key is null and null keys are invalid
*/
@Override
Set<V> remove(Object key);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Comparator;
/**
* Defines a type of {@code Bag} that maintains a sorted order among
* its unique representative members.
*
* @param <E> the type of elements in this bag
* @since 2.0
*/
public interface SortedBag<E> extends Bag<E> {
/**
* Returns the comparator associated with this sorted set, or null
* if it uses its elements' natural ordering.
*
* @return the comparator in use, or null if natural ordering
*/
Comparator<? super E> comparator();
/**
* Returns the first (lowest) member.
*
* @return the first element in the sorted bag
*/
E first();
/**
* Returns the last (highest) member.
*
* @return the last element in the sorted bag
*/
E last();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Comparator;
import java.util.SortedMap;
/**
* Defines a map that allows bidirectional lookup between key and values
* and retains both keys and values in sorted order.
* <p>
* Implementations should allow a value to be looked up from a key and
* a key to be looked up from a value with equal performance.
* </p>
*
* @param <K> the type of the keys in the map
* @param <V> the type of the values in the map
* @since 3.0
*/
public interface SortedBidiMap<K, V> extends OrderedBidiMap<K, V>, SortedMap<K, V> {
/**
* Gets a view of this map where the keys and values are reversed.
* <p>
* Changes to one map will be visible in the other and vice versa.
* This enables both directions of the map to be accessed equally.
* <p>
* Implementations should seek to avoid creating a new object every time this
* method is called. See {@code AbstractMap.values()} etc. Calling this
* method on the inverse map should return the original.
* <p>
* Implementations must return a {@code SortedBidiMap} instance,
* usually by forwarding to {@code inverseSortedBidiMap()}.
*
* @return an inverted bidirectional map
*/
@Override
SortedBidiMap<V, K> inverseBidiMap();
/**
* Get the comparator used for the values in the value-to-key map aspect.
* @return Comparator&lt;? super V&gt;
*/
Comparator<? super V> valueComparator();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.collections4.collection.UnmodifiableCollection;
import org.apache.commons.collections4.iterators.UnmodifiableMapIterator;
import org.apache.commons.collections4.map.EntrySetToMapIteratorAdapter;
import org.apache.commons.collections4.map.UnmodifiableEntrySet;
import org.apache.commons.collections4.set.UnmodifiableSet;
/**
* Utilities for working with "split maps:" objects that implement {@link Put}
* and/or {@link Get} but not {@link Map}.
*
* @since 4.0
*
* @see Get
* @see Put
*/
public class SplitMapUtils {
/**
* Don't allow instances.
*/
private SplitMapUtils() {}
private static class WrappedGet<K, V> implements IterableMap<K, V>, Unmodifiable {
private final Get<K, V> get;
private WrappedGet(final Get<K, V> get) {
this.get = get;
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
@Override
public boolean containsKey(final Object key) {
return get.containsKey(key);
}
@Override
public boolean containsValue(final Object value) {
return get.containsValue(value);
}
@Override
public Set<Map.Entry<K, V>> entrySet() {
return UnmodifiableEntrySet.unmodifiableEntrySet(get.entrySet());
}
@Override
public boolean equals(final Object arg0) {
if (arg0 == this) {
return true;
}
return arg0 instanceof WrappedGet && ((WrappedGet<?, ?>) arg0).get.equals(this.get);
}
@Override
public V get(final Object key) {
return get.get(key);
}
@Override
public int hashCode() {
return ("WrappedGet".hashCode() << 4) | get.hashCode();
}
@Override
public boolean isEmpty() {
return get.isEmpty();
}
@Override
public Set<K> keySet() {
return UnmodifiableSet.unmodifiableSet(get.keySet());
}
@Override
public V put(final K key, final V value) {
throw new UnsupportedOperationException();
}
@Override
public void putAll(final Map<? extends K, ? extends V> t) {
throw new UnsupportedOperationException();
}
@Override
public V remove(final Object key) {
return get.remove(key);
}
@Override
public int size() {
return get.size();
}
@Override
public Collection<V> values() {
return UnmodifiableCollection.unmodifiableCollection(get.values());
}
@Override
public MapIterator<K, V> mapIterator() {
final MapIterator<K, V> it;
if (get instanceof IterableGet) {
it = ((IterableGet<K, V>) get).mapIterator();
} else {
it = new EntrySetToMapIteratorAdapter<>(get.entrySet());
}
return UnmodifiableMapIterator.unmodifiableMapIterator(it);
}
}
private static class WrappedPut<K, V> implements Map<K, V>, Put<K, V> {
private final Put<K, V> put;
private WrappedPut(final Put<K, V> put) {
this.put = put;
}
@Override
public void clear() {
put.clear();
}
@Override
public boolean containsKey(final Object key) {
throw new UnsupportedOperationException();
}
@Override
public boolean containsValue(final Object value) {
throw new UnsupportedOperationException();
}
@Override
public Set<Map.Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
@Override
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
return obj instanceof WrappedPut && ((WrappedPut<?, ?>) obj).put.equals(this.put);
}
@Override
public V get(final Object key) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return ("WrappedPut".hashCode() << 4) | put.hashCode();
}
@Override
public boolean isEmpty() {
throw new UnsupportedOperationException();
}
@Override
public Set<K> keySet() {
throw new UnsupportedOperationException();
}
@Override
@SuppressWarnings("unchecked")
public V put(final K key, final V value) {
return (V) put.put(key, value);
}
@Override
public void putAll(final Map<? extends K, ? extends V> t) {
put.putAll(t);
}
@Override
public V remove(final Object key) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
throw new UnsupportedOperationException();
}
@Override
public Collection<V> values() {
throw new UnsupportedOperationException();
}
}
/**
* Get the specified {@link Get} as an instance of {@link IterableMap}.
* If {@code get} implements {@link IterableMap} directly, no conversion will take place.
* If {@code get} implements {@link Map} but not {@link IterableMap} it will be decorated.
* Otherwise an {@link Unmodifiable} {@link IterableMap} will be returned.
* @param <K> the key type
* @param <V> the value type
* @param get to wrap, must not be null
* @return {@link IterableMap}
* @throws NullPointerException if the argument is null
*/
@SuppressWarnings("unchecked")
public static <K, V> IterableMap<K, V> readableMap(final Get<K, V> get) {
Objects.requireNonNull(get, "get");
if (get instanceof Map) {
return get instanceof IterableMap ?
((IterableMap<K, V>) get) :
MapUtils.iterableMap((Map<K, V>) get);
}
return new WrappedGet<>(get);
}
/**
* Get the specified {@link Put} as an instanceof {@link Map}.
* If {@code put} implements {@link Map} directly, no conversion will take place.
* Otherwise a <em>write-only</em> {@link Map} will be returned. On such a {@link Map}
* it is recommended that the result of #put(K, V) be discarded as it likely will not
* match {@code V} at runtime.
*
* @param <K> the key type
* @param <V> the element type
* @param put to wrap, must not be null
* @return {@link Map}
* @throws NullPointerException if the argument is null
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> writableMap(final Put<K, V> put) {
Objects.requireNonNull(put, "put");
if (put instanceof Map) {
return (Map<K, V>) put;
}
return new WrappedPut<>(put);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Defines a functor interface implemented by classes that transform one
* object into another.
* <p>
* A {@code Transformer} converts the input object to the output object.
* The input object should be left unchanged.
* Transformers are typically used for type conversions, or extracting data
* from an object.
* </p>
* <p>
* Standard implementations of common transformers are provided by
* {@link TransformerUtils}. These include method invocation, returning a constant,
* cloning and returning the string value.
* </p>
*
* @param <I> the input type to the transformer
* @param <O> the output type from the transformer
*
* @since 1.0
*/
@FunctionalInterface
public interface Transformer<I, O> {
/**
* Transforms the input object (leaving it unchanged) into some output object.
*
* @param input the object to be transformed, should be left unchanged
* @return a transformed object
* @throws ClassCastException (runtime) if the input is the wrong class
* @throws IllegalArgumentException (runtime) if the input is invalid
* @throws FunctorException (runtime) if the transform cannot be completed
*/
O transform(I input);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import java.util.SortedMap;
/**
* Defines the interface for a prefix tree, an ordered tree data structure. For
* more information, see <a href="https://en.wikipedia.org/wiki/Trie">Tries</a>.
*
* @param <K> the type of the keys in this map
* @param <V> the type of the values in this map
* @since 4.0
*/
public interface Trie<K, V> extends IterableSortedMap<K, V> {
/**
* Returns a view of this {@link Trie} of all elements that are prefixed
* by the given key.
* <p>
* In a {@link Trie} with fixed size keys, this is essentially a
* {@link #get(Object)} operation.
* <p>
* For example, if the {@link Trie} contains 'Anna', 'Anael',
* 'Analu', 'Andreas', 'Andrea', 'Andres', and 'Anatole', then
* a lookup of 'And' would return 'Andreas', 'Andrea', and 'Andres'.
*
* @param key the key used in the search
* @return a {@link SortedMap} view of this {@link Trie} with all elements whose
* key is prefixed by the search key
*/
SortedMap<K, V> prefixMap(K key);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
import org.apache.commons.collections4.trie.UnmodifiableTrie;
/**
* A collection of {@link Trie} utilities.
*
* @since 4.0
*/
public class TrieUtils {
/**
* Don't allow instances.
*/
private TrieUtils() {}
/**
* Returns an unmodifiable instance of a {@link Trie}
*
* @param <K> the key type
* @param <V> the value type
* @param trie the trie to make unmodifiable, must not be null
* @return an unmodifiable trie backed by the given trie
* @throws NullPointerException if trie is null
*
* @see java.util.Collections#unmodifiableMap(java.util.Map)
*/
public static <K, V> Trie<K, V> unmodifiableTrie(final Trie<K, ? extends V> trie) {
return UnmodifiableTrie.unmodifiableTrie(trie);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;
/**
* Marker interface for collections, maps and iterators that are unmodifiable.
* <p>
* This interface enables testing such as:
* </p>
* <pre>
* if (coll instanceof Unmodifiable) {
* coll = new ArrayList(coll);
* }
* // now we know coll is modifiable
* </pre>
* Of course all this only works if you use the Unmodifiable classes defined
* in this library. If you use the JDK unmodifiable class via {@code java.util Collections}
* then the interface won't be there.
*
* @since 3.0
*/
public interface Unmodifiable {
// marker interface - no methods to implement
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.bag;
import java.util.Set;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.collection.AbstractCollectionDecorator;
/**
* Decorates another {@code Bag} to provide additional behavior.
* <p>
* Methods are forwarded directly to the decorated bag.
* </p>
*
* @param <E> the type of elements in this bag
* @since 3.0
*/
public abstract class AbstractBagDecorator<E>
extends AbstractCollectionDecorator<E> implements Bag<E> {
/** Serialization version */
private static final long serialVersionUID = -3768146017343785417L;
/**
* Constructor only used in deserialization, do not use otherwise.
* @since 3.1
*/
protected AbstractBagDecorator() {
}
/**
* Constructor that wraps (not copies).
*
* @param bag the bag to decorate, must not be null
* @throws NullPointerException if bag is null
*/
protected AbstractBagDecorator(final Bag<E> bag) {
super(bag);
}
/**
* Gets the bag being decorated.
*
* @return the decorated bag
*/
@Override
protected Bag<E> decorated() {
return (Bag<E>) super.decorated();
}
@Override
public boolean equals(final Object object) {
return object == this || decorated().equals(object);
}
@Override
public int hashCode() {
return decorated().hashCode();
}
@Override
public int getCount(final Object object) {
return decorated().getCount(object);
}
@Override
public boolean add(final E object, final int count) {
return decorated().add(object, count);
}
@Override
public boolean remove(final Object object, final int count) {
return decorated().remove(object, count);
}
@Override
public Set<E> uniqueSet() {
return decorated().uniqueSet();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.bag;
import java.util.Comparator;
import org.apache.commons.collections4.SortedBag;
/**
* Decorates another {@code SortedBag} to provide additional behavior.
* <p>
* Methods are forwarded directly to the decorated bag.
* </p>
*
* @param <E> the type of elements in this bag
* @since 3.0
*/
public abstract class AbstractSortedBagDecorator<E>
extends AbstractBagDecorator<E> implements SortedBag<E> {
/** Serialization version */
private static final long serialVersionUID = -8223473624050467718L;
/**
* Constructor only used in deserialization, do not use otherwise.
* @since 3.1
*/
protected AbstractSortedBagDecorator() {
}
/**
* Constructor that wraps (not copies).
*
* @param bag the bag to decorate, must not be null
* @throws NullPointerException if bag is null
*/
protected AbstractSortedBagDecorator(final SortedBag<E> bag) {
super(bag);
}
/**
* Gets the bag being decorated.
*
* @return the decorated bag
*/
@Override
protected SortedBag<E> decorated() {
return (SortedBag<E>) super.decorated();
}
@Override
public E first() {
return decorated().first();
}
@Override
public E last() {
return decorated().last();
}
@Override
public Comparator<? super E> comparator() {
return decorated().comparator();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.bag;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.collections4.Bag;
/**
* Decorates another {@link Bag} to comply with the Collection contract.
* <p>
* By decorating an existing {@link Bag} instance with a {@link CollectionBag},
* it can be safely passed on to methods that require Collection types that
* are fully compliant with the Collection contract.
* </p>
* <p>
* The method javadoc highlights the differences compared to the original Bag interface.
* </p>
*
* @see Bag
* @param <E> the type of elements in this bag
* @since 4.0
*/
public final class CollectionBag<E> extends AbstractBagDecorator<E> {
/** Serialization version */
private static final long serialVersionUID = -2560033712679053143L;
/**
* Factory method to create a bag that complies to the Collection contract.
*
* @param <E> the type of the elements in the bag
* @param bag the bag to decorate, must not be null
* @return a Bag that complies to the Collection contract
* @throws NullPointerException if bag is null
*/
public static <E> Bag<E> collectionBag(final Bag<E> bag) {
return new CollectionBag<>(bag);
}
/**
* Constructor that wraps (not copies).
*
* @param bag the bag to decorate, must not be null
* @throws NullPointerException if bag is null
*/
public CollectionBag(final Bag<E> bag) {
super(bag);
}
/**
* Write the collection out using a custom routine.
*
* @param out the output stream
* @throws IOException if an error occurs while writing to the stream
*/
private void writeObject(final ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeObject(decorated());
}
/**
* Read the collection in using a custom routine.
*
* @param in the input stream
* @throws IOException if an error occurs while reading from the stream
* @throws ClassNotFoundException if an object read from the stream can not be loaded
* @throws ClassCastException if deserialized object has wrong type
*/
@SuppressWarnings("unchecked") // will throw CCE, see Javadoc
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
setCollection((Collection<E>) in.readObject());
}
// Collection interface
/**
* <i>(Change)</i>
* Returns {@code true} if the bag contains all elements in
* the given collection, <b>not</b> respecting cardinality. That is,
* if the given collection {@code coll} contains at least one of
* every object contained in this object.
*
* @param coll the collection to check against
* @return {@code true} if the Bag contains at least one of every object in the collection
*/
@Override
public boolean containsAll(final Collection<?> coll) {
return coll.stream().allMatch(this::contains);
}
/**
* <i>(Change)</i>
* Adds one copy of the specified object to the Bag.
* <p>
* Since this method always increases the size of the bag, it
* will always return {@code true}.
*
* @param object the object to add
* @return {@code true}, always
*/
@Override
public boolean add(final E object) {
return add(object, 1);
}
@Override
public boolean addAll(final Collection<? extends E> coll) {
boolean changed = false;
for (final E current : coll) {
final boolean added = add(current, 1);
changed = changed || added;
}
return changed;
}
/**
* <i>(Change)</i>
* Removes the first occurrence of the given object from the bag.
* <p>
* This will also remove the object from the {@link #uniqueSet()} if the
* bag contains no occurrence anymore of the object after this operation.
*
* @param object the object to remove
* @return {@code true} if this call changed the collection
*/
@Override
public boolean remove(final Object object) {
return remove(object, 1);
}
/**
* <i>(Change)</i>
* Remove all elements represented in the given collection,
* <b>not</b> respecting cardinality. That is, remove <i>all</i>
* occurrences of every object contained in the given collection.
*
* @param coll the collection to remove
* @return {@code true} if this call changed the collection
*/
@Override
public boolean removeAll(final Collection<?> coll) {
if (coll != null) {
boolean result = false;
for (final Object obj : coll) {
final boolean changed = remove(obj, getCount(obj));
result = result || changed;
}
return result;
}
// let the decorated bag handle the case of null argument
return decorated().removeAll(null);
}
/**
* <i>(Change)</i>
* Remove any members of the bag that are not in the given collection,
* <i>not</i> respecting cardinality. That is, any object in the given
* collection {@code coll} will be retained in the bag with the same
* number of copies prior to this operation. All other objects will be
* completely removed from this bag.
* <p>
* This implementation iterates over the elements of this bag, checking
* each element in turn to see if it's contained in {@code coll}.
* If it's not contained, it's removed from this bag. As a consequence,
* it is advised to use a collection type for {@code coll} that provides
* a fast (e.g. O(1)) implementation of {@link Collection#contains(Object)}.
*
* @param coll the collection to retain
* @return {@code true} if this call changed the collection
*/
@Override
public boolean retainAll(final Collection<?> coll) {
if (coll != null) {
boolean modified = false;
final Iterator<E> e = iterator();
while (e.hasNext()) {
if (!coll.contains(e.next())) {
e.remove();
modified = true;
}
}
return modified;
}
// let the decorated bag handle the case of null argument
return decorated().retainAll(null);
}
// Bag interface
/**
* <i>(Change)</i>
* Adds {@code count} copies of the specified object to the Bag.
* <p>
* Since this method always increases the size of the bag, it
* will always return {@code true}.
*
* @param object the object to add
* @param count the number of copies to add
* @return {@code true}, always
*/
@Override
public boolean add(final E object, final int count) {
decorated().add(object, count);
return true;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.bag;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.collections4.SortedBag;
/**
* Decorates another {@link SortedBag} to comply with the Collection contract.
*
* @param <E> the type of elements in this bag
* @since 4.0
*/
public final class CollectionSortedBag<E> extends AbstractSortedBagDecorator<E> {
/** Serialization version */
private static final long serialVersionUID = -2560033712679053143L;
/**
* Factory method to create a sorted bag that complies to the Collection contract.
*
* @param <E> the type of the elements in the bag
* @param bag the sorted bag to decorate, must not be null
* @return a SortedBag that complies to the Collection contract
* @throws NullPointerException if bag is null
*/
public static <E> SortedBag<E> collectionSortedBag(final SortedBag<E> bag) {
return new CollectionSortedBag<>(bag);
}
/**
* Constructor that wraps (not copies).
*
* @param bag the sorted bag to decorate, must not be null
* @throws NullPointerException if bag is null
*/
public CollectionSortedBag(final SortedBag<E> bag) {
super(bag);
}
/**
* Write the collection out using a custom routine.
*
* @param out the output stream
* @throws IOException if an error occurs while writing to the stream
*/
private void writeObject(final ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeObject(decorated());
}
/**
* Read the collection in using a custom routine.
*
* @param in the input stream
* @throws IOException if an error occurs while reading from the stream
* @throws ClassNotFoundException if an object read from the stream can not be loaded
* @throws ClassCastException if deserialized object has wrong type
*/
@SuppressWarnings("unchecked") // will throw CCE, see Javadoc
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
setCollection((Collection<E>) in.readObject());
}
// Collection interface
@Override
public boolean containsAll(final Collection<?> coll) {
return coll.stream().allMatch(this::contains);
}
@Override
public boolean add(final E object) {
return add(object, 1);
}
@Override
public boolean addAll(final Collection<? extends E> coll) {
boolean changed = false;
for (final E current : coll) {
final boolean added = add(current, 1);
changed = changed || added;
}
return changed;
}
@Override
public boolean remove(final Object object) {
return remove(object, 1);
}
@Override
public boolean removeAll(final Collection<?> coll) {
if (coll != null) {
boolean result = false;
for (final Object obj : coll) {
final boolean changed = remove(obj, getCount(obj));
result = result || changed;
}
return result;
}
// let the decorated bag handle the case of null argument
return decorated().removeAll(null);
}
@Override
public boolean retainAll(final Collection<?> coll) {
if (coll != null) {
boolean modified = false;
final Iterator<E> e = iterator();
while (e.hasNext()) {
if (!coll.contains(e.next())) {
e.remove();
modified = true;
}
}
return modified;
}
// let the decorated bag handle the case of null argument
return decorated().retainAll(null);
}
// Bag interface
@Override
public boolean add(final E object, final int count) {
decorated().add(object, count);
return true;
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment