Non static comparator inner class - java

I would like to know is it ok to make non static inner class which implements comparator interface.
eg.
public class A {
private Map<String, Integer> scoreMap;
private final class myComparator implements Comparator<MyOtherClass> {
private int calScore(MyOtherClass ob) {
int score = ob.someValue * ob.otherValue;
scoreMap.put(ob.getName(), score);
}
public int compare(MyOtherClass ob1, MyOtherCLass ob2) {
return Integer.compare(calScore(ob1), calScore(ob2));
}
}
}
I would like to use comparator class non static because I want to use non static field "num" and want to modify its value. Is it fine to have non static comparator inner class?
Additional Info
For each object I am calculating score inside compare and sorting accordingly. I need to save those scores in a map which I calculated inside comparator and want to use this map in outer class for further calculation.

Technically nothing is stopping you. Morally however...
As long as you maintain the idempotency (run multiple times and get same result) then it is not incorrect. However it is a sideeffect. (use this comparator, and some class's values change. run another comparator and nothing changes). Side effects aren't necessarily bad but they make a program more complex and harder to understand and debug.
Try seeing it through the eyes of some poor soul that has to maintain your code. Some value changes and they have no idea why. all they did was compare an unaffiliated list.
anyways your example is very abstract so it's hard to judge the context but usually there is no need to do what you want to do. It is generally something to be avoided unless you have a really good reason for it. And that really good reason shouldn't be "because I don't want to loop over the dataset again" in my opinion.
from your edit:
You are trying to save yourself work by not having to do the recalculating again from the sounds of it. You're saving yourself only a small amount of effort really. why not first calculate the scores, store the result, then sort the results (on score field)
like:
public static class ScoredEntry {
private SomeGameData data; //or something
private int score;
// constructor takes data + score, imagine getters, setters, I am lazy ok.
}
public List<ScoredEntry> scoreEntries(List<SomeGameData> gameData) {
List<ScoredEntry> result = new ArrayList<ScoredEntry>();
for (SomeGameData data : gameData) {
int score = calculateScore(data);
result.add(new SCoredEntry(score, data);
}
return result;
}
public void sortBySCore(List<ScoredEntry> list) {
Collections.sort(list, new Comparator<ScoredEntry>() {
public int compare(SCoredEntry a, ScoredEntry b) {
// etcetera.
}
}
}

Related

Understanding Java Enum Methods Implementation through an Example

So, I'm working on a project right now for school with a few people and one of them has committed some code that I'm really having difficulty wrapping my head around. The basis of the project is creating a music library with songs, albums, and playlists. These playlists, in particular, are arraylists of songs need different ways of sorting and thus he's implemented comparator for sorting. He did so using enums, which I understand from the perspective of just instances to represent items. Like
public enum Suit {
SPADES, CLUBS, HEARTS, DIAMONDS
}
to represent different suits of a card. I also have learned you can declare methods alongside enums, which is what it looks like he did. Here is the attribute declaration area and the constructor:
public class Playlist implements Comparator<Song>{
private TotalTime aTotalTime;
private String aName;
private ArrayList<Song> playList;
private Comparator<Song> aComparator;
private enum Method{
SortByTitle(new Comparator<Song> () {
#Override
public int compare(Song o1, Song o2) {
// TODO Auto-generated method stub
return o2.getTitle().compareTo(o1.getTitle());
}
}),
SortByArtist(new Comparator<Song>() {
#Override
public int compare(Song o1, Song o2) {
// TODO Auto-generated method stub
return o2.getExpectedTags().getArtist().compareTo(o1.getExpectedTags().getArtist());
}
}),
SortByLength(new Comparator<Song>() {
#Override
public int compare(Song o1, Song o2) {
// TODO Auto-generated method stub
return o2.getTotalSeconds()-o1.getTotalSeconds();
}
});
private Comparator<Song> comparator;
Method(Comparator<Song> pComparator){
comparator = pComparator;
}
public Comparator<Song> getComparator(){
return this.comparator;
}
}
// constructor that initializes the the playlist.
public Playlist(String pName,Method aMethod) {
aName = new String(pName);
playList = new ArrayList<Song>();
this.aComparator = aMethod.getComparator();
}
}
I can vaguely follow what's going on here as such: We start with the constructor, which calls aMethod.getComparator(), with aMethod being the enum instance, and then aMethod.getComparator() returns the this.comparator object, which itself is declared three lines above as a private Comparator<Song> comparator. From my perspective, it looks like ithis will return the private comparator object every time and not actually change the sorting method of the Comparable interface. Any help parsing all of this would be greatly appreciated.
Your analysis is correct. This class seems strange. Some points which stand out:
Why is Playlist a Comparator of Songs? It may make more sense to allow the playlist to be sorted using a Method instead of passing on construction.
The Method provided has no impact on the order of Songs in the Playlist.
The Method enum probably should not be private.
It may be worth revisiting the scope of the components in the project.
What is a Playlist? Is it a different Playlist if the Song order has changed?
Should it be up to the Playlist to decide how to play the songs in the playlist?
Look only at the enum definition.
The enum definition defines 3 actual enums: SortByTitle, SortByLength, and SortByArtist - those are your SPADE, HEARTS, DIAMONDS, CLUBS; of this enum. For each value, they are initialized with a non-zero-length constructor, and the object passed is a custom impl of a comparator, but forget all that for now.
The enumeration (heh) of enum values then ends. Why? Because semicolon.
But the enum definition doesn't end yet; then we get private Comparator<Song> comparator;.
Note that each individual enum value gets its own copy of this field. Each value of an enum is itself an instance of the 'class' that the enum represents. And the key point here is that this field holds different comparators for SortByArtist, SortByLength, etc.
Therefore, Method.SortByArtist.getComparator(); returns the value of that field for the instance of the Method 'class' (enums are basically classes, with highly limited construction; only one instance per value, so 3 instances here, ever). Which is different from the value of that field for the SortByLength instance.
The rest is just anonymous inner classes.
This is valid java, I think it should be fairly obvious to tell, right?
class StringByLengthComparator implements Comparator<String> {
public int compare(String a, String b) {
return a.length() - b.length();
}
}
...
Comparator<String> c = new StringByLengthComparator();
but we can write that with less characters in java, using the concept 'anonymous inner classes'. This works when you make a class and then intent to use this definition exactly once, and then never use it again. Let's say this 'Comparator c = ...;' line is the only place in the entire code base that you're ever going to mention StringByLengthComparator by name. Then:
Comparator<String> c = new Conmparator<String>() {
public int compare(String a, String b) {
return a.length() - b.length();
}
};
Looks funky, but it means the exact same thing. The one difference is that this class, which still exists, is not named StringByLengthComparator, but it gets a random name you needn't worry about and cannot ever use. That's okay though - after all, this was the only place we were ever gonna use this thing.
Java lambdas.
Note that you can make this even shorter, using lambda syntax:
Comparator<String> c = (a, b) -> a.length() - b.length();
still means the same thing (well, the object you get no longer has presence, which only matters if you do very silly things, such as relying on its object identity hashcode, or lock on the comparator itself, which are all crazy things to do. So if you don't do anything crazy, it's the same thing).
That's what the code is doing. It's no different than first defining 3 classes that each implement Comparable<Song>, and then passing new SongsByLengthComparer() as expression as first argument.

Ordering objects in java *without* using values

I want to create a class of objects to compare to each other, without using values to compare them with. Is there a library in Java which is able to provide this functionality for me? In terms of ordering, the most frequently mentioned library is Comparator, but all the examples I have seen so far use some kinds of value from the objects in order to perform this ordering with.
For example, I want to be able to say that within a class of objects that:
Object A is more important than Object B.
Object B is more important than Object C.
Therefore, I want the library to be able to perform some kind of analysis, and to be able to order the items according to these values, and say to me, that the order of the values above are A, B, C, in that order.
Is there a library which is able to do this in Java?
Are you thinking of something like this?
enum Importance {
High,
Medium,
Low;
}
class Thing implements Comparable<Thing> {
private Importance importance = Importance.Medium;
public Importance getImportance() {
return importance;
}
public void setImportance(Importance importance) {
this.importance = importance;
}
#Override
public int compareTo(Thing o) {
return importance.compareTo(o.importance);
}
}
Alternatively - if you want to control the relativity of each object then record that in a Map. You will need to be careful to tightly control the map to ensure there are no cycles - if there is then your sorting will become unstable.
static Map<Thing, Set<Thing>> moreImportant = new HashMap<>();
class Thing implements Comparable<Thing> {
#Override
public int compareTo(Thing o) {
Set<Thing> more = moreImportant.get(this);
return more == null ? 0 : more.contains(o) ? 1 : -1;
}
}

Require input regarding JAVA ENUMS

Consider the following
public enum tc implements {
NORESULTS(0), GOOD_RESULTS(1), EXCELLENT_RESULTS(2), NO_DATA_AVAILABLE(5), SOME_OTHER_VALUE(4);
private final Integer value;
// Code for the constructor, getters and setters for the value****
The enum tc values correspond to the testValue in the below class.
public class TestData {
private int testID;
private String testName;
private int testValue;
....
...
}
In the Results class, the TestDataList has to be sorted by a different order of ranking rather than testValue.For example Excellent followed by Good Results followed by NoResults etc..
public class Results {
List<TestData> TestDataList = getTestData();
I can code for the comparator etc..the question is since I require a different ordering for the enums which of the following two options is better
a) add private int rankTestValue in the enum tc. This option may require that I have to write a method getRank(int value) that would return the corresponding rankTestValue based on the value.
OR
b) add in Results class a map Map tcRankMap = new HashMap();. Populate this map with key values like (2,1) (1,2) corresponding to (enum values, ranking).For example (2,1) would be Excellent_Results has first ranking etc.
Which of these two options would be better. If there are better solutions then please let me know.
Option (a) looks better and according to Object Oriented Analysis and Design.
The good news is that the is a question of implementation detail which can be encapsulated into your Comparator anyway, so it doesn't matter so much.
As for style and readability, I would prefer (a), but it's down to personal preference.
There is also a solution (c) - use the ordinal(), and then sort them according to rank. Just add a comment to make it clear
public enum tc implements {
// NB: enum values are sorted according to rank
EXCELLENT_RESULTS(2),
GOOD_RESULTS(1),
NORESULTS(0),
NO_DATA_AVAILABLE(5),
SOME_OTHER_VALUE(4);
private final Integer value;
// Code for the constructor, getters and setters for the value****
}
Your first option would look like this:
enum TestScore {
EXCELLENT(5),
NO_RESULT(2),
POOR(1);
private final int order;
private TestScore(int order) {
this.order = order;
}
public int compareOrderTo(TestScore other) {
return this.order - other.order;
}
}
You could then add a comparison method to TestData
public int compareTestScore(TestData other) {
return this.testScore.compareOrderTo(other.testScore);
}
And sort your list with:
Collections.sort(testData, TestData::compareTestScore);
The problem with this is that the order field is really completely arbitrary and needs to be updated each time you add a new entry. However that's definitely better and more explicit than using the natural ordering of the enum (i.e. it's ordinal value which should be entirely incidental to avoid fragility).

How can I best make a class hold something for another class?

I'm encountering a couple awkward situations that seem, in some sense, dual to each other, and was wondering if anyone had any thoughts about how to handle them cleanly.
External initialization
class Human {
Collection <Human> nextDoorNeighbors;
}
class Neighborhood {
Collection <Human> humans;
Neighborhood() {
// Make humans
// Then, let them all know who their neighbors are.
}
}
This is awkward because the humans (in this situation) never have to change their next-door neighbors once they've been set up (they are effectively write-once), but this setup can't be done in the Human constructor because the neighbors that need to be put in the nextDoorNeighbors collection don't all exist when the human is constructed.
Holding something for another
Suppose I want to be able to store Humans in a tree-based map. To do so, the Human has to hold a Comparable ID, even if that isn't logically significant to the concept of a Human. The Human constructs this ID, but it never uses it. Only the map uses it (or even should use it).
In the first case, maybe the awkwardness is an indication that neighbours shouldn't be a property of Human. Perhaps the Neighbourhood object should be a property of Human, and a method like human.getNeighbours() can be used to get the actual neighbours when they are needed. Then having a neighbours property becomes a private performance issue for the getNeighbours() method.
In the second case, how is your tree-based map providing a structure if the Human is inherently unstructurable? What's the map for if the ID is irrelevant to the human? Typically an ID is relevant, and is used by the class that has it to ensure that it's uniquely identifiable, but if it's genuinely not required, you can use a separate class, like a HumanKey, to wrap the Human for the map.
I don't really understant what your question is.. Because it's not explicit..
But for the id you can have a static variable in the human class that you will increment in the human constructor and another variable wich will contain the id
It would be something like this
class Human
{
private static int humansCounter=0;
final public int id;
public Human()
{
id=humansCounter++;
}
}
I have an approach that I think is rather clean if the objects themselves need to be aware of the networking. Note that this approach will not work if you concurrently instantiate instances (since each thread will have its own copy of the static fields).
class Foo {
// instance fields
public Foo(/* constructor args */) {
// set instance up
network(this);
}
public boolean isNeighbor(Foo that) {
return areNeighbors(this, that);
}
// static field for tracking edges between neighbors, maybe a
private static Map<Foo, List<Foo>> neighborhood = new HashMap<>();
private static void network(Foo me) {
myNeighbors = new ArrayList<>();
for (Map.Entry<Foo, List<Foo>> x : neighborhood.entrySet()) {
Foo n = x.getKey();
if (/* use me and n's fields to determine whether they are neighbors */) {
myNeighbors.add(n);
x.getValue().add(me);
}
}
neighborhood.put(me, myNeighbors);
}
public static boolean areNeighbors(Foo a, Foo b) {
return neighborhood.get(a).contains(b);
}
}
This approach makes it so that each instance can determine their neighbors without actually knowing their neighbors ahead of time and without using an external class. If an instance's neighbors cannot be inferred from internal state, this approach could be combined with the approach of generating unique IDs (hashes?) for each instance:
class Bar {
// instance fields
public Bar(/* constructor args */, int... neighborIndices) {
// set instance up
network(this, neighborIndices);
}
#Override
public int hashCode() {
return /* a unique value based upon this object's state */;
}
public boolean isNeighbor(Bar that) {
return areNeighbors(this, that);
}
private static Map<Integer, Bar> lookup = new HashMap<>();
private static Map<Bar, List<Integer>> neighbors = new HashMap<>();
private static void network(Bar me, int[] neighbors) {
lookup.put(me.hashCode(), me);
List<Integer> neighborList = new ArrayList<>();
for (int i : neighbors) {
neighborList.add(i);
}
neighbors.put(me, neighborList);
}
public static boolean areNeighbors(Bar a, Bar b) {
return neighbors.get(a).contains(b.hashCode());
}
}
Naturally, if the neighbor relationships are not associative, it is trivial to modify the first example to be a digraph.

Java: When to use attributes, when to use method parameters?

I tried googling and searching for this question but somehow couldn't find anything relevant about it. I'm wondering if there is a bbest-practise guide on when to use attributes in a class and when not, but rather use parameters to the single methods.
Many cases are clear to me, e.g.
public class Dog
{
private name;
public setName(...) {....}
}
But sometimes it's not clear to me what's better to use.
E.g. the following, either use:
public class calculation
XYZ bla;
public calculation(XYZ something)
{
this.bla = something;
}
public void calc1()
{
// some calculations with this.bla
}
public void calc1()
{
// some more calculations with this.bla
}
public XYZ getBla()
{
return this.bla;
}
}
or maybe do:
public class calculation
public calculation() {}
public static XYZ calc1(XYZ bla) // maybe static, if not dependant on other attributes/instance-variables etc
{
// some calculations with bla
return bla;
}
public static XYZ calc1() // maybe static, if not dependant on other attributes/instance-variables etc
{
// some more calculations with bla
return bla;
}
}
I mean you can argue for both cases. I see advantages and maybe disadvantages for both different styles, but somehow I prefer the second one as far as long as there are not too many arguments/parameters needed. Sure, if I need many many more attributes etc., then the first one will be better, simpler etc. because I dont need to pass so many parameters to the method...
Just a question of personal style?
Or how to decide for one approach?
Thanks
EDIT: A better example: I'm curently doing much image processing and the question would be wether to store the image internally in the state of the object or not. I'm currently NOT doing it because I'm using static methods, and psasing the image itself I to each method:
public class ImageProcessing
{
/**
*
*/
public static Mat cannyEdges(Mat I, int low, int high)
{
// ...
return I;
}
public static Mat cannyEdges(Mat I)
{
return ImageProcessing.cannyEdges(I, ContourDetection.CANNY_LOWTHRES, ContourDetection.CANNY_HIGHTHRES);
}
/**
*
*/
public static Mat getHoughLines(Mat Edges, ...some_conf_vars...)
{
// ...
return I;
}
}
and then I'm calling it from the outside like this e.g.:
// here: read image to I...
Mat edges = ImageProcessing.cannyEdges(I, 20, 100);
Mat lines = ImageProcessing.getHoughLines(I);
// draw lines...
question is: Does I belong to the state of the object? Would it make sense to convert to non-static and then use for example:
// here: read image to I...
ImageProcessing IP = new ImageProcessing(I);
IP.cannyEdges(20, 100); // CHANGE OF cannyEdges: Also save `edges` internally as property!?
IP.calcHoughLines(); // also save the lines internally maybe?
Mat lines = IP.getLines();
// draw lines...
is this nicer?
The question arising is then again: Should I for example store the result of getHoughLines() (i.e. the lines) internally or should I directly return it to the caller!?
I can use some examples:
public class Multiplier {
private int number;
public Multiplier(int number) {
this.number = number;
}
public int multiply(int other) {
return number * other;
}
}
This class could be instantiated like:
Multiplier multiplyByTwo = new Multiplier(2);
I could use it to multiply many elements on a list by 2.
But I could need to multiply pairs of numbers. So the following class could be what I neeed:
public class Multiplier {
public static int multiply(int number, int other) {
return number * other;
}
}
I could make it static since no state is needed.
This example could be used like this on a list:
for (int x:listOfInts) {
print(Multiplier.multiply(x * 2));
}
But probably in this specific case the 1st example was nicer.
for (int x:listOfInts) {
print(multiplyByTwo(x));
}
or even nicer used with a Java 8 ''map''
If I need to get the elements of the multiplication and the result at many points in my code i could do.
class Multiplier {
private int x;
private int y;
public int multiply() {
return x * y;
}
// getters and setters for x and y
}
In this last case I may consider not adding setters and pass x, y in the constructor.
Every structure could be used in some specific cases.
It's not entirely a question of personal style. But nevertheless, I assume that this topic might be slightly controversial (opinion-based) and thus not perfectly suited for a Q/A-site.
However, the obvious question is: Does an object of the respective class really carry a state? That is, is there any benefit in having the state represented by an instance? If the sole purpose of the instance is to be an accumulator of variables that are modified with a sequence of set... calls and a final call to an execute() method, then there is usually no real justification for such an instance - except for avoiding to have a static method with "many" parameters.
I think that the advantages of static methods outweigh most of the potential clumsiness of calling a method with "many" parameters. One of the most important ones is probably that the approach with static methods doesn't increase the state space. Every field is another dimension in the state space, and documenting state space properly can be hard. Static methods enforce a more "functional" programming style: They don't have any side-effects, and thus, are thread-safe (which is becoming increasingly important).
(Note: All this refers to static methods that are not related to any static state - that should be avoided anyhow. And of course, this refers to methods that are not involved in or aiming at anything related to polymorphism).
And after all, one can easily call any static method from anywhere - even from within an instance method, and pass in some fields as parameters. The opposite is not so easy: When you want to call a method that depends on many instance fields, it can be a hassle when you first have to create an object and set the fields appropriately (still not knowing whether it is in a valid state to call the method). I also see the default methods of Java 8 as a nice application case where static utility methods come in handy: The default method may easily delegate to the utility method, because no state is involved.
There are a few reasons I'd go with the first option, i.e. an object with state over static functions, particularly for complex calculations but also for simpler ones.
Objects work better for the command pattern.
Objects work better for the strategy pattern.
Static methods can turn unit tests into a nightmare.
Static is an anti-pattern in OOP because it breaks polymorphism, with the side-effect that related techniques will break with it, e.g. open/closed, mocking, proxies, etc.
That's my 2c at least.
The weird part of your first example is that those calcX methods don't say anything about idempotency, so it's unclear what this.bla is when it's being manipulated. For complex computations with optional settings, an alternative is to construct an immutable object using a builder pattern, and then offer calcX methods that return the result based on fixed object state and parameters. But the applicability of that really depends on the use case, so YMMV.
Update: With your new code, a more OOP approach would be to decorate Mat. Favouring delegation over inheritance, you'd get something like
public class MyMat
{
private Mat i;
public MyMat(Mat i) {
this.i = i;
}
public Mat getBackingMat() {
return this.i;
}
public MyMat cannyEdges(int low, int high)
{
// ...
return new MyMat(I); // lets you chain operations
}
public MyMat cannyEdges()
{
return new MyMat(ImageProcessing.cannyEdges(I, ContourDetection.CANNY_LOWTHRES, ContourDetection.CANNY_HIGHTHRES));
}
public MyMat getHoughLines(...some_conf_vars...)
{
// ...
}
}
MyMat myMat = new MyMat(I);
lines = myMat.cannyEdges(20, 100).calcHoughLines();
This is just a guess, cause I have no idea what those things mean. :)
When not to use static:
If the result that will be returned is dependent on other variables (state) that make up your "calculation" class then static cannot be used.
However, if you are simply doing calculations on a variable, as the example implies, static is probably the way to go as it requires less code (For example to perform calc1 and then calc2 on a variable by the first method you would have to do:
calculation calc = new calculation(x)
calc.calc1();
calc.calc2();
XYZ y = calc.getBla();
while with the second example you could do
static import ...calculation.*;
...
XYZ y = calc2(calc1(x));

Categories