Java tutorial
/* * Copyright 2015 by Yields. * * Licensed 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 io.yields.math.framework.property; import org.apache.commons.lang.Validate; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import io.yields.math.framework.FunctionalContext; import io.yields.math.framework.Property; public class SortedProperty<T extends Comparable<T>> implements Property<List<T>> { private static final String LABEL = "sorted"; private boolean increasing; private Comparator<T> comparator; private static final double EPS = 1.e-8; private final String explanation; protected SortedProperty(boolean increasing, Class<T> clazz, String explanation) { this.increasing = increasing; if (clazz.equals(Double.class) || clazz.equals(double.class)) { this.comparator = new Comparator<T>() { @Override public int compare(T o1, T o2) { return compareDouble(o1, o2); } }; } else { this.comparator = new Comparator<T>() { @Override public int compare(T o1, T o2) { return o1.compareTo(o2); } }; } this.explanation = explanation; } @Override public boolean isValid(List<T> value, FunctionalContext<List<T>> context) { Validate.notEmpty(value, "An empty collection cannot be ordered."); int sign = increasing ? 1 : -1; List<T> sorted = value.stream().sorted((t1, t2) -> sign * t1.compareTo(t2)).collect(Collectors.toList()); return IntStream.range(0, value.size()) .allMatch(index -> comparator.compare(sorted.get(index), value.get(index)) == 0); } @Override public String getLabel() { return LABEL; } private int compareDouble(Object tx, Object ty) { double x = (double) tx; double y = (double) ty; if (Math.abs(x - y) < EPS) { return 0; } else { return Double.compare(x, y); } } @Override public String getExplanation() { return explanation; } }