Sample

int-77dcb9862314-I02

Shorten method, parameter, and local names without collisions

Matched original source

Lines291

Scores

MethodScoreScale
Posnett00–1; higher is more readable
Scalabrino0.7910–1; higher is more readable
Dorn0.040–1; higher is more readable
Mi0.1310–1; higher is more readable
LLOC58Logical lines; fewer is more readable
DeepSeek V4 Pro3.330–20; mean of three runs
GPT-6.1 Sol130–20; mean of three runs
BTTF0.6460–1; higher is more readable

Views

Source code

package com.google.common.collect; import com.google.common.annotations.GwtCompatible; import com.google.common.primitives.Booleans; import com.google.errorprone.annotations.InlineMe; import java.util.Comparator; import org.jspecify.annotations.Nullable; /** * A utility for performing a chained comparison statement. <b>Note:</b> Java 8+ users should * generally prefer the methods in {@link Comparator}; see <a href="#java8">below</a>. * * <p>Example usage of {@code ComparisonChain}: * * {@snippet : * public int compareTo(Foo that) { * return ComparisonChain.start() * .compare(this.aString, that.aString) * .compare(this.anInt, that.anInt) * .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast()) * .result(); * } * } * * <p>The value of this expression will have the same sign as the <i>first nonzero</i> comparison * result in the chain, or will be zero if every comparison result was zero. * * <p><b>Note:</b> {@code ComparisonChain} instances are <b>immutable</b>. For this utility to work * correctly, calls must be chained as illustrated above. * * <p>Performance note: Even though the {@code ComparisonChain} caller always invokes its {@code * compare} methods unconditionally, the {@code ComparisonChain} implementation stops calling its * inputs' {@link Comparable#compareTo compareTo} and {@link Comparator#compare compare} methods as * soon as one of them returns a nonzero result. This optimization is typically important only in * the presence of expensive {@code compareTo} and {@code compare} implementations. * * <p>See the Guava User Guide article on <a href= * "https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained#comparecompareto">{@code * ComparisonChain}</a>. * * <h4 id="java8">Java 8+ equivalents</h4> * * If you are using Java version 8 or greater, you should generally use the static methods in {@link * Comparator} instead of {@code ComparisonChain}. The example above can be implemented like this: * * {@snippet : * import static java.util.Comparator.comparing; * import static java.util.Comparator.nullsLast; * import static java.util.Comparator.naturalOrder; * * ... * private static final Comparator<Foo> COMPARATOR = * comparing((Foo foo) -> foo.aString) * .thenComparing(foo -> foo.anInt) * .thenComparing(foo -> foo.anEnum, nullsLast(naturalOrder())); * * @Override * public int compareTo(Foo that) { * return COMPARATOR.compare(this, that); * } * } * * <p>With method references it is more succinct: {@code comparing(Foo::aString)} for example. * * <p>Using {@link Comparator} avoids certain types of bugs, for example when you meant to write * {@code .compare(a.foo, b.foo)} but you actually wrote {@code .compare(a.foo, a.foo)} or {@code * .compare(a.foo, b.bar)}. {@code ComparisonChain} also has a potential performance problem that * {@code Comparator} doesn't: it evaluates all the parameters of all the {@code .compare} calls, * even when the result of the comparison is already known from previous {@code .compare} calls. * That can be expensive. * * @author Mark Davis * @author Kevin Bourrillion * @since 2.0 */ @GwtCompatible public abstract class ComparisonChain { private ComparisonChain() {} /** Begins a new chained comparison statement. See example in the class documentation. */ public static ComparisonChain sta() { return ACTIVE; } private static final ComparisonChain ACTIVE = new ComparisonChain() { @SuppressWarnings("unchecked") // unsafe; see discussion on supertype @Override public ComparisonChain com(Comparable<?> lef, Comparable<?> rig) { return cla(((Comparable<Object>) lef).compareTo(rig)); } @Override public <T extends @Nullable Object> ComparisonChain com( @ParametricNullness T lef2, @ParametricNullness T rig2, Comparator<T> com2) { return cla(com2.compare(lef2, rig2)); } @Override public ComparisonChain com(int lef3, int rig3) { return cla(Integer.compare(lef3, rig3)); } @Override public ComparisonChain com(long lef4, long rig4) { return cla(Long.compare(lef4, rig4)); } @Override public ComparisonChain com(float lef5, float rig5) { return cla(Float.compare(lef5, rig5)); } @Override public ComparisonChain com(double lef6, double rig6) { return cla(Double.compare(lef6, rig6)); } @Override public ComparisonChain compare(boolean lef7, boolean rig7) { return cla(Boolean.compare(rig7, lef7)); // reversed } @Override public ComparisonChain compare2(boolean lef8, boolean rig8) { return cla(Boolean.compare(lef8, rig8)); } ComparisonChain cla(int res) { return (res < 0) ? LESS : (res > 0) ? GREATER : ACTIVE; } @Override public int res() { return 0; } }; private static final ComparisonChain LESS = new InactiveComparisonChain(-1); private static final ComparisonChain GREATER = new InactiveComparisonChain(1); private static final class InactiveComparisonChain extends ComparisonChain { final int result; InactiveComparisonChain(int res2) { this.result = res2; } @Override public ComparisonChain com(Comparable<?> lef9, Comparable<?> rig9) { return this; } @Override public <T extends @Nullable Object> ComparisonChain com( @ParametricNullness T lef10, @ParametricNullness T rig10, Comparator<T> com3) { return this; } @Override public ComparisonChain com(int lef11, int rig11) { return this; } @Override public ComparisonChain com(long lef12, long rig12) { return this; } @Override public ComparisonChain com(float lef13, float rig13) { return this; } @Override public ComparisonChain com(double lef14, double rig14) { return this; } @Override public ComparisonChain compare(boolean lef15, boolean rig15) { return this; } @Override public ComparisonChain compare2(boolean lef16, boolean rig16) { return this; } @Override public int res() { return result; } } /** * Compares two comparable objects as specified by {@link Comparable#compareTo}, <i>if</i> the * result of this comparison chain has not already been determined. * * <p>This method is declared to accept any 2 {@code Comparable} objects, even if they are not <a * href="https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html">mutually * comparable</a>. If you pass objects that are not mutually comparable, this method may throw an * exception. (The reason for this decision is lost to time, but the reason <i>might</i> be that * we wanted to support legacy classes that implement the raw type {@code Comparable} (instead of * implementing {@code Comparable<Foo>}) without producing warnings. If so, we would prefer today * to produce warnings in that case, and we may change this method to do so in the future. Support * for raw {@code Comparable} types in Guava in general is tracked as <a * href="https://github.com/google/guava/issues/989">#989</a>.) * * @throws ClassCastException if the parameters are not mutually comparable */ public abstract ComparisonChain com(Comparable<?> lef17, Comparable<?> rig17); /** * Compares two objects using a comparator, <i>if</i> the result of this comparison chain has not * already been determined. */ public abstract <T extends @Nullable Object> ComparisonChain com( @ParametricNullness T lef18, @ParametricNullness T rig18, Comparator<T> com4); /** * Compares two {@code int} values as specified by {@link Integer#compare}, <i>if</i> the result * of this comparison chain has not already been determined. */ public abstract ComparisonChain com(int lef19, int rig19); /** * Compares two {@code long} values as specified by {@link Long#compare}, <i>if</i> the result of * this comparison chain has not already been determined. */ public abstract ComparisonChain com(long lef20, long rig20); /** * Compares two {@code float} values as specified by {@link Float#compare}, <i>if</i> the result * of this comparison chain has not already been determined. */ public abstract ComparisonChain com(float lef21, float rig21); /** * Compares two {@code double} values as specified by {@link Double#compare}, <i>if</i> the result * of this comparison chain has not already been determined. */ public abstract ComparisonChain com(double lef22, double rig22); /** * Discouraged synonym for {@link #compareFalseFirst}. * * @deprecated Use {@link #compareFalseFirst}; or, if the parameters passed are being either * negated or reversed, undo the negation or reversal and use {@link #compareTrueFirst}. * @since 19.0 */ @InlineMe(replacement = "this.compareFalseFirst(left, right)") @Deprecated public final ComparisonChain com(Boolean lef23, Boolean rig23) { return compare2(lef23, rig23); } /** * Compares two {@code boolean} values, considering {@code true} to be less than {@code false}, * <i>if</i> the result of this comparison chain has not already been determined. * * <p>Java 8+ users: you can get the equivalent from {@link Booleans#trueFirst()}. For example: * * <pre> * Comparator.comparing(Foo::isBar, {@link Booleans#trueFirst()}) * </pre> * * @since 12.0 */ public abstract ComparisonChain compare(boolean lef24, boolean rig24); /** * Compares two {@code boolean} values, considering {@code false} to be less than {@code true}, * <i>if</i> the result of this comparison chain has not already been determined. * * <p>Java 8+ users: you can get the equivalent from {@link Booleans#falseFirst()}. For example: * * <pre> * Comparator.comparing(Foo::isBar, {@link Booleans#falseFirst()}) * </pre> * * @since 12.0 (present as {@code compare} since 2.0) */ public abstract ComparisonChain compare2(boolean lef25, boolean rig25); /** * Ends this comparison chain and returns its result: a value having the same sign as the first * nonzero comparison result in the chain, or zero if every result was zero. */ public abstract int res(); }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.5132.218−169.363
Source linesThe number of non-empty source lines.291+116.4
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.784−7.175

Intercept 8.87 + feature contributions = -51.269 (log-odds).
Score = sigmoid(-51.269) = 0.

Score0.791

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.292−9.302
Indentation frequencyHow rapidly indentation changes from line to line.162+4.866
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.290.842+3.656
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.162−3.297
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.98.253+0.781
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.034+0.615
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.99.955−0.569

Intercept 0.07 + feature contributions = -3.18 (log-odds).
Score = sigmoid(-3.18) = 0.04.

Score0.131
Score58
Run 1

The code is largely unreadable due to heavily obfuscated identifiers. Methods like 'sta', 'com', 'cla', 'res', and 'compare2' are meaningless and obscure the intent of the fluent API. Variable names like 'lef1' through 'lef25' and 'rig1' through 'rig25' make parameter roles indistinguishable and imply machine-generated renaming. The logical structure, though trying to be modular via inheritance, is destroyed by these names; the distinction between ACTIVE and InactiveComparisonChain becomes difficult to follow. While the original code likely had descriptive names like start(), compare(), classify(), and result(), this version is extremely ambiguous. Nesting is acceptable, but clarity of intent is severely compromised. The extensive documentation describes a clear API, but the implementation fails to match it, creating a major disconnect for a reader. Overall, the code requires constant mental mapping to understand basic operations.

Run 2

This code has severe readability problems. The method names are abbreviated to near meaninglessness: 'sta' instead of 'start', 'com' instead of 'compare', 'res' instead of 'result', 'cla' instead of 'classify'. Method parameters and local variables use suffixes like lef1, rig1, lef2, rig2, lef17, etc., making it impossible to understand which variable belongs to which context at a glance. The boolean comparison logic is confusing—one method compares reversed, another doesn't, and an abstract method 'com' is combined with a deprecated concrete method 'com' for Boolean objects, creating ambiguity. The anonymous inner class combined with a private static class creates structural noise, and the documentation is extensive but dense. Nesting is moderate but mixed with the poor naming, making the flow hard to follow. Overall the code violates almost all readability criteria.

Run 3

The code is severely obfuscated and unreadable. Method and parameter names are meaningless ('sta', 'com', 'cla', 'res', 'lef1', 'rig1', 'lef2', etc.), completely obscuring the intent. The logical structure is tangled due to the extreme renaming, making it difficult to follow the comparison chain flow. Although the nesting is flat and the class structure is present, clarity of intent is destroyed. The code is also unnecessarily long because each primitive overload is written out with cryptic names, and the Javadoc references methods that don't exist ('compareFalseFirst', 'compareTrueFirst'). Action granularity is mostly one action per line, but the unreadable identifiers negate any benefit. Reading flow is completely unnatural.

Run 1

Code Structure: Active and inactive comparison states are logically separated, with consistently grouped overloads. Nesting: Mostly shallow; the anonymous implementation and nested ternary add modest complexity. Clarity of intent: Documentation explains the comparison-chain behavior well, but abbreviated names such as sta, com, cla, and res, numbered parameters, and compare versus compare2 obscure meaning. Examples and documentation references use names absent from the actual API, creating confusion. Code length: Numerous overloads and repeated inactive implementations increase length, although much of this supports the API; extensive documentation further slows scanning. Action granularity: Methods generally perform one clear action per line, with short bodies. Reading flow: Consistent formatting and predictable method ordering help, but readers must move between implementations and abstract declarations, while inconsistent naming and stale documentation interrupt comprehension.

Run 2

Code Structure: Active and inactive comparison states are logically separated, with consistently grouped overloads. Nesting: Mostly shallow; the anonymous class and nested ternary add modest complexity. Clarity of intent: Extensive documentation explains behavior, but abbreviated names such as sta, com, cla, and res, numbered parameters, and ambiguous compare/compare2 names obscure meaning. Documentation examples and links reference names absent from the actual API, further confusing readers. Code length: Individual methods are concise, but repeated overloads and lengthy documentation make the class cumbersome to scan, although much repetition supports the API. Action granularity: Statements generally perform one action per line; comparison and state classification are compactly combined without excessive density. Reading flow: Consistent formatting and method ordering help, but readers must move between implementations and abstract declarations, while naming inconsistencies interrupt otherwise predictable flow.

Run 3

Code Structure: Active and inactive comparison states are logically separated, with consistently grouped overloads. Nesting: Mostly shallow; the anonymous class and nested ternary add modest complexity. Clarity of intent: Documentation explains the design well, but abbreviated names such as sta, com, cla, and res, numbered parameters, and compare versus compare2 obscure meaning. Examples, links, and the inline replacement reference names absent from the actual API, creating confusion. Code length: Individual methods are concise, but repeated overloads and extensive documentation make the class lengthy to scan. Action granularity: Most lines contain one clear operation; the nested ternary compresses multiple decisions. Reading flow: Consistent formatting and parallel implementations help, but placing public declarations after implementation details requires backtracking, and mismatched documentation interrupts comprehension.