i want to do nested sorting . I have a course object which has a set of applications .Applications have attributes like time and priority. Now i want to sort them according to the priority first and within priority i want to sort them by time.
For example, given this class (public fields only for brevity):
public class Job {
public int prio;
public int timeElapsed;
}
you might implement sorting by time using the static sort(List, Comparator) method in the java.util.Collections class. Here, an anonymous inner class is created to implemented the Comparator for "Job". This is sometimes referred to as an alternative to function pointers (since Java does not have those).
public void sortByTime() {
AbstractList<Job> list = new ArrayList<Job>();
//add some items
Collections.sort(list, new Comparator<Job>() {
public int compare(Job j1, Job j2) {
return j1.timeElapsed - j2.timeElapsed;
}
});
}
Mind the contract model of the compare() method: http://java.sun.com/javase/6/docs/api/java/util/Comparator.html#compare(T,%20T)
Take a look at the Google Collections Ordering class at http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Ordering.html. It should have everything you need plus more. In particular you should take a look at the compound method to get your second ordering.
To sort on multiple criteria, a couple of common approches using the Comparable interface:
write your compareTo() method so that it compares one field, and then goes on to compare the other if it can't return an ordering based on the first;
if you're careful then again, in your compareTo() method, you can translate a combination of both criteria into a single integer that you can then compare.
The first of these approaches is usually preferable and more likely to be correct (even though the code ends up looking a bit more cumbersome).
See the example on my web site of making Java objects sortable, which shows an example of sorting playing cards by suit and number within the suits.
You've already asked this question elsewhere. Write an implementation of java.util.Comparator.
Subtracting the two numbers as in the example above is not always a good idea.
Consider what would happen if you compared -2,147,483,644 with 2,147,483,645. Subtracting them would cause an integer overflow and thus a positive number. A positive number means would cause the comparator to claim that -2,147,483,644 is larger than 2,147,483,645.
-5 - 6 = -7
-2,147,483,644 - 2,147,483,645 = 1
Subtracting to find the compare value is even more dangerous when you consider comparing longs or doubles, since that have to be cast back to ints providing another opportunity for an overflow. For example, never do this:
class ZardozComparorator implements Comparator<Zardoz>{
public int compare(Zardoz z1, Zardoz z2) {
Long z1long = Long.getLong(z1.getName());
Long z2long = Long.getLong(z2.getName());
return (int)(z1long-z2long);
}
}
Instead use the compare method of the object you are comparing. That way you can avoid overflows and if needed you can override the compare method.
class ZardozComparorator implements Comparator<Zardoz>{
public int compare(Zardoz z1, Zardoz z2) {
Long z1long = Long.getLong(z1.getName());
Long z2long = Long.getLong(z2.getName());
return z1long.compareTo(z2long);
}
}
Here is my opinion for this 7 year old question that still gets reported sometimes:
Make a static method in your object like (only if you use other libraries to autogenerate getters and setters):
public static String getNameFrom(Order order){
return order.name;
}
Then try to use something like this:
Collections.sort(orders, Comparator.comparing(Order::getNameFrom));
For a more elegand approach I always prefer not change the entity, but use more advanced coding with Lambdas. For example:
Collections.sort(orders, (order1, order2) ->
order1.name.compareTo(order2.name);
Related
I was just exploring different kinds of implementations to the hashCode() method. I opened up the java.lang.Integer class and found this implementation for hashCode():
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
My question is, why can't the implementation be as simple as:
public int hashCode(){
return this.value;
}
What is the need to create an additional static method to pass around the value and return the same? Am I overlooking any important detail here?
That code does look odd when viewed on its own.
But notice that the static method java.lang.Integer.hashCode:
was added later, in Java 8
is public
The source code in Java 14 shows no comments to explain why this static method was added. Because the method is public, I presume this new static method plays a part in some new feature in Java 8, perhaps related to streams, called elsewhere in the OpenJDK codebase.
As noted in the Javadoc, the source code of the existing Integer::hashCode instance method was rewritten to call the static hashCode simply for consistency. This way there is only one place where the hash code is actually being generated. Having only one place is wise for review and maintenance of the codebase.
Making hashCode static is certainly unusual. The purpose of the hashCode method is to identify one object of that class to another for use in collections such as HashSet or HashMap. Given that we are comparing instances by the method, it makes sense for hashCode to be an instance method rather than static.
The optimizing compiler such as HotSpot or OpenJ9 is likely to inline the hashCode method calls, making moot the instance-method versus static-method arrangement in source code.
#Basil Bourque's answer covers just about everything. But he leaves open the question of why the public static void hashCode(int) was added.
The change was made in this changeset in November 2012
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/be1fb42ef696/src/share/classes/java/lang/Integer.java
The title and summary for the changeset say this:
7088913: Add compatible static hashCode(primitive) to primitive wrapper classes
Summary: Adds static utility methods to each primitive wrapper class to allow calculation of a hashCode value from an unboxed primitive.
Note that the changeset does not document the motivation for the change.
I infer that one purpose of the enhancement is to avoid the application programmer having to know how the primitive wrapper classes are computed. Prior to Java 8, to compute the wrapper-compatible hash code for a primitive int, the programmer would have to have written either
int value = ...
int hash = ((Integer) value).hashCode(); // Facially inefficient (depending on
// JIT compiler's ability to get
// rid of the box/unbox sequence)
or
int value = ...
int hash = value; // Hardwires knowledge of how
// Integer.hashCode() is computed.
While the "knowledge" is trivial for int / Integer, consider the case of double / Double where the hash code computation is:
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
It seems likely that this changeset was also motivated by the Streams project; e.g. so that Integer::hashCode can be used in a stream of integers.
However, the changeset that added sum, min and max for use in stream reductions happened a couple of months after this one. So we cannot definitively make the connection ... based on this evidence.
I can't find any information on this anywhere and was wondering whether such a use of a class is considered bad practise or not.
Let me explain. I have a class ToDecimalConverter which converts an integer from any base to decimal. However, I now need to add the functionality to also convert fractions. As such, I abstracted the integer conversion into a separate class and created a new class with the purpose of converting fractions. (Code isn't finished so I just added some comments to explain)
public class ToDecimalConverter {
private IntegerToDecimalConverter integerConverter;
private DoubleToDecimalConverter doubleConverter;
public double convert(String number, int baseNumber) {
this.integerConverter = new IntegerToDecimalConverter();
this.doubleConverter = new DoubleToDecimalConverter();
number = this.removeZerosAtBeginningOfNumber(number);
// split the number into integer and fraction so they can be used below:
int decimalInt = this.integerConverter.convert(integerNumber, baseNumber);
double decimalDouble = this.doubleConverter.convert(fractioNumber, baseNumber);
// add them together and return them
}
}
Now, except for the methods that remove the zero's from the start of a number and the method that splits the number into integer and fraction (both of which can easily be abstracted into their own class), the ToDecimalConverter class does nothing but group the integer and fraction converters together.
When searching online, I don't see a lot of classes being used like this. Should this be avoided or not? and if so, what are alternatives?
This meant as a more general question, the above is just to explain what I mean.
Edit: Or should I see it as a sort of mini GoF Facade pattern?
There is nothing wrong with it by default, but I would guess that you could achieve the same result with two methods. something like:
public int convertFromInt(String number, int baseNumber) {
int theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
public double convertFromFraction(String number, int baseNumber) {
double theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
Also, keep in mind that a lot of this conversions are already done by Java native classes like BigInteger, BigDecimal, Integer, Decimal, Double, the Math package and so on.
Not going into the specifics of what your class is doing, there indeed value in grouping several or many function/classes together to from a single unified API.
This is called the Facade design pattern.
The intent is that instead of relying on your client to have to know of the various classes/objects you use internally to achieve a feature and to have to look all over the place inside your implementation code is that you put in place a single entry point for given feature/set of feature. It is much better for discoverability & documentation.
Also this way, you ensure to only provide the public API that is only one or a few classes that make the facade while the implementation remains hidden and can change at any time.
Say I have a List of object which were defined using lambda expressions (closures). Is there a way to inspect them so they can be compared?
The code I am most interested in is
List<Strategy> strategies = getStrategies();
Strategy a = (Strategy) this::a;
if (strategies.contains(a)) { // ...
The full code is
import java.util.Arrays;
import java.util.List;
public class ClosureEqualsMain {
interface Strategy {
void invoke(/*args*/);
default boolean equals(Object o) { // doesn't compile
return Closures.equals(this, o);
}
}
public void a() { }
public void b() { }
public void c() { }
public List<Strategy> getStrategies() {
return Arrays.asList(this::a, this::b, this::c);
}
private void testStrategies() {
List<Strategy> strategies = getStrategies();
System.out.println(strategies);
Strategy a = (Strategy) this::a;
// prints false
System.out.println("strategies.contains(this::a) is " + strategies.contains(a));
}
public static void main(String... ignored) {
new ClosureEqualsMain().testStrategies();
}
enum Closures {;
public static <Closure> boolean equals(Closure c1, Closure c2) {
// This doesn't compare the contents
// like others immutables e.g. String
return c1.equals(c2);
}
public static <Closure> int hashCode(Closure c) {
return // a hashCode which can detect duplicates for a Set<Strategy>
}
public static <Closure> String asString(Closure c) {
return // something better than Object.toString();
}
}
public String toString() {
return "my-ClosureEqualsMain";
}
}
It would appear the only solution is to define each lambda as a field and only use those fields. If you want to print out the method called, you are better off using Method. Is there a better way with lambda expressions?
Also, is it possible to print a lambda and get something human readable? If you print this::a instead of
ClosureEqualsMain$$Lambda$1/821270929#3f99bd52
get something like
ClosureEqualsMain.a()
or even use this.toString and the method.
my-ClosureEqualsMain.a();
This question could be interpreted relative to the specification or the implementation. Obviously, implementations could change, but you might be willing to rewrite your code when that happens, so I'll answer at both.
It also depends on what you want to do. Are you looking to optimize, or are you looking for ironclad guarantees that two instances are (or are not) the same function? (If the latter, you're going to find yourself at odds with computational physics, in that even problems as simple as asking whether two functions compute the same thing are undecidable.)
From a specification perspective, the language spec promises only that the result of evaluating (not invoking) a lambda expression is an instance of a class implementing the target functional interface. It makes no promises about the identity, or degree of aliasing, of the result. This is by design, to give implementations maximal flexibility to offer better performance (this is how lambdas can be faster than inner classes; we're not tied to the "must create unique instance" constraint that inner classes are.)
So basically, the spec doesn't give you much, except obviously that two lambdas that are reference-equal (==) are going to compute the same function.
From an implementation perspective, you can conclude a little more. There is (currently, may change) a 1:1 relationship between the synthetic classes that implement lambdas, and the capture sites in the program. So two separate bits of code that capture "x -> x + 1" may well be mapped to different classes. But if you evaluate the same lambda at the same capture site, and that lambda is non-capturing, you get the same instance, which can be compared with reference equality.
If your lambdas are serializable, they'll give up their state more easily, in exchange for sacrificing some performance and security (no free lunch.)
One area where it might be practical to tweak the definition of equality is with method references because this would enable them to be used as listeners and be properly unregistered. This is under consideration.
I think what you're trying to get to is: if two lambdas are converted to the same functional interface, are represented by the same behavior function, and have identical captured args, they're the same
Unfortunately, this is both hard to do (for non-serializable lambdas, you can't get at all the components of that) and not enough (because two separately compiled files could convert the same lambda to the same functional interface type, and you wouldn't be able to tell.)
The EG discussed whether to expose enough information to be able to make these judgments, as well as discussing whether lambdas should implement more selective equals/hashCode or more descriptive toString. The conclusion was that we were not willing to pay anything in performance cost to make this information available to the caller (bad tradeoff, punishing 99.99% of users for something that benefits .01%).
A definitive conclusion on toString was not reached but left open to be revisited in the future. However, there were some good arguments made on both sides on this issue; this is not a slam-dunk.
To compare labmdas I usually let the interface extend Serializable and then compare the serialized bytes. Not very nice but works for the most cases.
I don't see a possibility, to get those informations from the closure itself.
The closures doesn't provide state.
But you can use Java-Reflection, if you want to inspect and compare the methods.
Of course that is not a very beautiful solution, because of the performance and the exceptions, which are to catch. But this way you get those meta-informations.
This question already has answers here:
How to implement the Java comparable interface?
(9 answers)
Closed 6 years ago.
I have a token class that uses object identity (as in equals just returns tokenA == tokenB). I'd like to use it in a TreeSet. This means that I need to implement a comparison between two tokens that is compatible with reference equality.I don't care about the specific implementation, so long as it is consistent with equals and fulfills the contract (as per TreeSet: "Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface.")
Note: these tokens are created on multiple threads, and may be compared on different threads than they were created on.
What would be the best method to go about doing so?
Ideas I've tried:
Using System.identityHashCode - the problem with this is that it is not guaranteed that two different objects will always have a different hashcode. And due to the birthday paradox you only need about 77k tokens before two will collide (assuming that System.identityHashCode is uniformly distributed over the entire 32-bit range, which may not be true...)
Using a comparator over the default Object.toString method for each token. Unfortunately, under the hood this just uses the hash code (same thing as above).
Using an int or long unique value (read: static counter -> instance variable). This bloats the size, and makes multithreading a pain (not to mention making object creation effectively singlethreaded) (AtomicInteger / AtomicLong for the static counter helps somewhat, but its the size bloat that's more annoying here).
Using System.identityHashCode and a static disambiguation map for any collisions. This works, but is rather complex. Also, Java by default doesn't have a ConcurrentWeakValueHashMultiMap (isn't that a mouthful), which means that I've got to pull in an external dependency (or write my own - probably using something similar to this) to do so, or suffer a (slow) memory leak, or use finalizers (ugh). (And I don't know if anyone implements such a thing...)
By the way, I can't simply punt the problem and assume unique objects have unique hash codes. That's what I was doing, but the assertion fired in the comparator, and so I dug into it, and, lo and behold, on my machine the following:
import java.util.*;
import java.util.Collections.*;
import java.lang.*;
public class size {
public static void main(String[] args) {
Map<Integer, Integer> soFar = new HashMap<>();
for (int i = 1; i <= 1_000_000; i++) {
TokenA t = new TokenA();
int ihc = System.identityHashCode(t);
if (soFar.containsKey(ihc)) {
System.out.println("Collision: " + ihc +" # object #" + soFar.get(ihc) + " & " + i);
break;
}
soFar.put(ihc, i);
}
}
}
class TokenA {
}
prints
Collision: 2134400190 # object #62355 & 105842
So collisions definitely do exist.
So, any suggestions?
There is no magic:
Here is the problem tokenA == tokenB compares identity, tokenA.equals(tokenB) compares whatever is defined in .equals() for that class regardless of identity.
So two objects can have .equals() return true and not be the same object instance, they don't even have to the the same type or share a super type.
There is no short cuts:
Implementing compareTo() is whatever you want to compare that are attributes of the objects. You just have to write the code and make it do what you want, but compareTo() is probably not what you want. compareTo() is for comparisons, if you two things are not < or > each other in some meaningful way then Comparable and Comparator<T> are not what you want.
Equals that is identity is simple:
public boolean equals(Object o)
{
return this == o;
}
As its a pain to handle structural changes of the class in two places I often do:
class A {
class C{}
class B{}
private B bChild;
private C cChild;
private Object[] structure() {
return new Object[]{bChild, cChild};
}
public int hashCode() {
Arrays.hashCode(structure());
}
public boolean equals(Object that) {
//type check here
return Arrays.equals(this.structure(), ((A)that).structure());
}
}
What's bad about this approach besides boxing of primitives?
Can it be improved?
It's a clever way to reuse library methods, which is generally a good idea; but it does a great deal of excess allocation and array manipulation, which might be terribly inefficient in such frequently used methods. All in all, I'd say its cute, but it wouldn't pass a review.
In JDK 7 they added the java.util.Objects class. It actually implements a hash and equals utility in a manner that reminds what you wrote. The point being that this approach is actually sanctioned by JDK developers. Ernest Friedman-Hill has a point but in the majority of cases I don't think that the extra few machine instructions are worth saving at the expense of readability.
For example: the hash utility method is implemented as:
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
Someone familiarizing themselves with the code will have a bit more difficulty seeing what's going on. It's less "obvious" than listing the individual fields, as demonstrated by my previously erroneous answer. It is true, that "equals" is generally implemented with an "Object" passed in, so it's debatable, but the input is cast after the reference equality check. That is not the case here.
One improvement might be to store the array as a private data member rather than create it with the structure method, sacrificing a bit of memory to avoid the boxing.