Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
FieryBalrog
Apr 7, 2010
Grimey Drawer
I'm fairly new to Java so my knowledge is pretty limited. I'm working on a personal project where I'm trying out some of the techniques used in Guava for creating views/transformations of collections. I made a class called View to take an inputted collection as the backing iterable, and a transformation, and then present it as a read-only iterable. (not a collection, though I don't think it makes much of a difference for this question). Here is a quick example of using it...
code:
public class View<T> implements Iterable<T> {
    private final Iterable<T> view;

    public <F> View(final Iterable<? extends F> originalSet,
            final Function<? super F, ? extends T> transform) {
        this.view = Views.transformReadOnly(originalSet, transform);
    }
    //other constructors
}

public final class Views {
    private Views() { }

    public static <F, T> Iterable<T> transformReadOnly(final Iterable<F> fromIterable,
            final Function<? super F, ? extends T> function) {
        checkNotNull(fromIterable);
        checkNotNull(function);
      return new FluentIterable<T>() {
          @Override
          public Iterator<T> iterator() {
            return ViewIterators.transformReadOnly(fromIterable.iterator(), function);
          }
      };
    }
    //other static methods
}
code:
public class Node {
  public enum Change implements Function<Node, Coordinate> {
    TO_COORDINATE;
    @Override public Coordinate apply(Node node) {
      return new Coordinate(node);
    }
  }

  private HashSet<Node> neighborNodes = new HashSet<Node>();
  //various other members

  public View<Coordinate> viewNeighborCoordinates() {
    return new View<Coordinate>(neighborNodes, Change.TO_COORDINATE);
  }
}
now if some method wants to use viewNeighborCoordinates() of this node, and then later some other method also wants to viewNeighborCoordinates() of this node, it seems wasteful to always be returning new objects, right? I mean any number of things should be able to share reference to a view of the same backing iterable with the same transformation, since all they're doing is reading through it. Is there an established way of managing a shared pool of objects which can be "interned" like Strings are? Is it just having to make some sort of ViewFactory that stores a running list of views in use, and everytime someone wants a view, it checks to see if it already has that view and hands it out? (is that even more efficient)?

Also, the same applies to iterating through the View, I guess, since the transformation calls the constructor of the target type via the function application when doing the actual iteration (so each time it iterates it will create a bunch of new objects for viewing purposes). Is it worth managing that somehow?

FieryBalrog fucked around with this message at 23:58 on Aug 11, 2014

Adbot
ADBOT LOVES YOU

FieryBalrog
Apr 7, 2010
Grimey Drawer

Sedro posted:

Did you just implement "map", ie. this?
Java code:
public class Node {
  private HashSet<Node> neighborNodes = new HashSet<Node>();
  //various other members

  public View<Coordinate> viewNeighborCoordinates() {
    return neighborNodes.map(Coordinate::new);
  }
}

Um, I'm not sure what you mean. There isn't any method named "map" as far as I can tell for HashSet...? I've never seen that syntax before either, is this a java 8 thing? (I'm a SQL guy and i don't know anything about programming except the last 2 months of learning Java from scratch, so maybe I'm missing something...).

The basic idea is the same as the one in Guava's Iterables & Iterators libraries, except it's read-only (remove() throws unsupported operation exception from the Iterator) and I added other ways of transforming a backing iterable.

code:
    public <X, F> View(X agent, final Iterable<? extends F> originalSet,
            final BinaryFunction<? super X, ? super F, ? extends T> catalyzer) {
        this.view = Views.catalyzeReadOnly(agent, originalSet, catalyzer);
    }

    public View(final Iterable<? extends T> originalSet) {
        this.view = Views.flattenReadOnly(originalSet);
    }

FieryBalrog fucked around with this message at 00:06 on Aug 12, 2014

FieryBalrog
Apr 7, 2010
Grimey Drawer
This might be a nitpick, but this bothers me
code:
for (Circle fromArray : listOfCircles) 
Can't we just have (Circle circle : listOfCircles)

FieryBalrog
Apr 7, 2010
Grimey Drawer
So I spent a good 6 months at my job teaching myself Java. I have a SQL background of 2 years and at the time I had zero programming knowledge outside of that, so it was both hard and a ton of fun to learn Java the language. I made my own pet project as a way of teaching myself all about type safety, interfaces, inheritance, type erasure, blah blah blah. I think I have a fairly good grasp of that stuff. What I most enjoyed was playing with generics and guava - stuff like FluentIterable, Multimap, etc. All on Java 7 last year.

Then I got put on an enterprise project involving a ton of Java and another 6 months later I realized that 99% of my time is spent wrestling with Spring & Camel xml files and Maven configuration problems and most of the actual coding is boilerplate setting values and basic if statements :eng99:

So uh, I guess my question is... is it always like this? If so, I want to go back to optimizing SQL queries because gently caress this noise

FieryBalrog
Apr 7, 2010
Grimey Drawer

Squashy Nipples posted:

Yeah, I'm a big fan of clear, descriptive variable names... the kids I'm trying to teach keep wanting to use single letter variable names like "a". :rolleyes:
I've tried telling them that it will come back to bite them in the rear end, but when they push back I can't give concrete reasons why... I just know from experience.

At the same time, it is a bit annoying that I end up with a bunch of variable, method and class names that literally look like the following:

EquilendSettlementToAutoborrowTransformerConcrete { }
processParsedSharedTradeTicketMessages()
etc.

I do it anyway, but sigh a little inside.

Squashy Nipples posted:

Also, its taking me a while to get used to the Java variable naming conventions, I really miss prefixing with the variable type, as it makes them stand out to me.
Like, lngRow strFileName and poo poo like that. Why do we not do that in Java?

This is terrible (hungarian notation), don't do this. You can literally mouse over the variable in an IDE and know the type instantly, it's a strongly typed language. On top of that my mind would explode if I had to prefix (super long variable name) with (super long class name) every time, it's already bad enough that you have to write:

code:
List<JavaClassNameThatIsWayTooFuckingLongForItsOwnGood> listOfStuff = new ArrayList<JavaClassNameThatIsWayTooFuckingLongForItsOwnGood>();

FieryBalrog fucked around with this message at 17:22 on Oct 7, 2015

FieryBalrog
Apr 7, 2010
Grimey Drawer

Gravity Pike posted:

Arcane generics/inheritance typing question:

Java code:
public class Scratch {
    public static void main(String... args) throws Exception {
        final Generic<Generic<Object>> noExtend = null;
        final Generic<Generic<? extends Object>> doesExtend = null;

        doThing(noExtend); //Generic<Generic<Object>> cannot be converted to Generic<Generic<? extends Object>>
        doThing(doesExtend);
    }

    public static class Generic<T> {};

    public static <T> Object doThing(Generic<Generic<? extends T>> arg1) {
        return null;
    }
}
Why can't List<List<Object>> be converted to List<List<? extends Object>>?

This took me a while to get, but basically I think the reason is this:

(1) List<? extends Object> means a list that can be read as an object but can't be written to as an object
(2) List<Object> can be read or written to as an object
(3) List<List<? extends Object> means a list that can have lists of type (1) written and read to it
(4) List<List<Object> means a list that can have lists of type (2) written and read to it

But type (1) is not type (2) (for compile time purposes, obviously the run-time type is the same.), even if type (1) can be assigned from type (2) (in this case, by removing the ability to write to (1)). Anything you add to a List<Object> is guaranteed to be readable as an object for the case of (1). That's why this is allowed, because (1) is not writeable.

However, (3) is writeable, it's not List<? extends T>, it's List<T>.

If (3) could be assigned from (4), that means you could add an unwriteable list of type (1) to (3) that is not compatible with the contract of (4) which guarantees that the Lists you get from it are writeable and readable (i.e., they are List<Object> and not List<? extends Object>. Or, conversely, it would mean that you couldn't add something of type (1) to (3) even though the contract of (3) specifies that you can.

TLDR: It's the same reason List<Object> can't be assigned from List<String>. If it were allowed, one of the two contracts would have to be violated:
a) you would have to prevent adding stuff to the List<Object> (since this could break List<String>)
or
b) you would have to prevent reading stuff from List<String> (since otherwise you could read a non-String that was added via List<Object>.

However, you can instead do:
(5) List<? extends List<Object>>, because this can be assigned from type 4 in the same fashion that 1 is assigned from 2.

That's why you can do the following:
code:
        List<Object> listObj = new ArrayList<Object>();
        List<? extends Object> listExtendsObj = listObj;
        List<List<Object>> listOfListObj = new ArrayList<List<Object>>();
        
        List<List<? extends Object>> listOfListExtendsObj = listOfListObj; //compile error
        
        List<? extends List<Object>> listExtendsListOfObj = listOfListObj; //no error

	List<Object> o = new ArrayList<String>(); //not allowed for similar reasons

FieryBalrog fucked around with this message at 18:21 on Oct 7, 2015

FieryBalrog
Apr 7, 2010
Grimey Drawer

crimedog posted:

Is it bad that my variables for Lists always have List at the end?

code:
List<String> lastnameList;

It's totally fine if it helps you understand what the variable is for...

That's why I think this is pointless:
code:
String strLastName = "Obama";
Integer intDistinctValueCount = 8;
and, by corollary, any rule that requires adding str for String or int for Integer and so on is dumb and pointless and occasionally downright detrimental.

But of course there's a huge number of situations where yeah, the type might be useful in the name because it helps you use the object.
code:
Date currentDate = Calendar.getInstance().getTime();
TradeOrderResponse tradeOrderResponse = new TradeOrderResponse();
Random rand = new Random();
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);

FieryBalrog
Apr 7, 2010
Grimey Drawer

pepito sanchez posted:

code:
private void renderCards() {
    for (Player p : game.getPlayers()) {
        icoCard1.setIcon(new ImageIcon(getClass().getResource(p.getHand().get(0).getImage())));
        icoCard2.setIcon(new ImageIcon(getClass().getResource(p.getHand().get(1).getImage())));
        icoCard3.setIcon(new ImageIcon(getClass().getResource(p.getHand().get(2).getImage())));
        icoCard4.setIcon(new ImageIcon(getClass().getResource(p.getHand().get(3).getImage())));
        icoCard5.setIcon(new ImageIcon(getClass().getResource(p.getHand().get(4).getImage())));
        icoCard6.setIcon(new ImageIcon(getClass().getResource(p.getHand().get(5).getImage())));
        icoCard7.setIcon(new ImageIcon(getClass().getResource(p.getHand().get(6).getImage())));
    }
}

pepito sanchez posted:

The problem I ran into is with rendering cards to each player's separate JFrame. At the moment I'm attempting to solve this with a foreach loop, and setting icons based on the player's hand. However... this only updates the UI of the last player to join.

I don't know anything about Swing at all, but it looks like you're overwriting the same objects for each player... That would perfectly explain why only the last player gets UI updated.

code:
Integer[] intArray = new Integer[] {1,2,3,4};
List<Integer> integers = Arrays.asList(intArray);
String s = null;

for (Integer i : integers) {
  s = i.toString();
}
System.out.println("s: " + s);
What do you think the value of the string will be...

FieryBalrog
Apr 7, 2010
Grimey Drawer
It still blows my mind that Java hasn't overridden the == operator on String to mean the same thing as equals().

AFAIK you already can't rely on String == comparison for reference equality because of interning, and in any case it sounds to my newbie ears like a horrible practice to rely on distinguishing String references for code to work.

FieryBalrog
Apr 7, 2010
Grimey Drawer
Yup. On the other hand:

code:
        String s1 = "abcde";
        String s2 = "abcde";

        System.out.println(s1 == s2);
        Object o1 = s1;
        Object o2 = s2;
        System.out.println(s1 == o2);
        System.out.println(s2 == o2);
        System.out.println(o1 == o2);

        String s3 = new String("abcde");
        System.out.println(s2 == s3);
code:
true
true
true
true
false
So it's not like you can know ahead of time which String was created with new and which was created with a literal...

In any case, I don't know what the answer would be for existing null comparisons. Maybe it's way too late to do this. Or maybe they just change equals itself.

Something that has always bothered me about equals() is that a.equals(b) throws NPE when a is null but not when b is null. Equality seems like it should behave symmetrically, without respect to the state of either input to the comparison, which is also something that the contract of course specifies (outside of the null case). Yeah it's a method on an object, but it's also special! Wouldn't it have been better if it just never threw NPE? Is there any technical reason why a == b never needs to throw null pointer but a.equals(b) can't be changed to do the same?

FieryBalrog fucked around with this message at 00:26 on Oct 15, 2015

FieryBalrog
Apr 7, 2010
Grimey Drawer

Jabor posted:

Note that you can use the static function Objects.equals(a, b) if you want a null-safe equality check.

This is exactly what I wanted! Why doesn't everyone use this as standard?

I'm trying to think of situations where you want equals invocation to throw NPE and I can't think of very many.

FieryBalrog
Apr 7, 2010
Grimey Drawer

baka kaba posted:

Well you don't generally want to throw NPEs. It's usually a sign that something's gone wrong and you either need to fix it (if it's something you control), or you need to safely handle the problem.

So using a method that doesn't care about nulls means you're doing a detour around that checking - which is sometimes fine! But if you expect an object to always be non-null, there's no point allowing that error through. Plus it'll break your comparison logic, now you're getting nulls returning true for equals() when you expect them to return false

It will never replace a previously false return with true... all it will do is replace NPE with an actual return. Either true if both are null, or false if a is null and b is not.

What I mean is, I dont think I should be relying on equals() to catch misplaced null objects, right? Either I actually care about the null object behavior, in which case I will get a proper NPE whenever I actually try to use the object for something I care about. Or else, I don't, and so who cares? I just get to stop using pointless defensive null checks.

Like anytime the code could be written as:
code:
if (a != null && a.equals(b)) { ... }
This is already intended to dodge the NPE because the programmer doesn't give a poo poo here about the NPE. And that's what I'm hypothesizing, that equality is not really object behavior. It's object state comparison and there's no reason to break down and crash because the object state you're looking at for a state comparison is null. There's no reason (or little reason) for a.equals(b) to throw an NPE when a==b doesn't and b.equals(a) might not either, given the state of b.

The arbitrary asymmetry in throwing the exception especially strikes me as making this exception on equals() pointless as a null-reference guard dog. You would have to write a.equals(b) && b.equals(a) if you wanted that. Correct me if I'm missing something.

I mean the Collections interface already demonstrates this is by specifically working around it. For example, contains(Object o) is defined as : there is an element e such that (o == null ? e == null : o.equals(e) )

FieryBalrog fucked around with this message at 05:16 on Oct 15, 2015

FieryBalrog
Apr 7, 2010
Grimey Drawer

baka kaba posted:

I mean situations where you're checking a.equals(b) without null-checking a first, because you expect it to be a valid object, but there's a possibility of a bunch of nulls passing through b. If your assumption ever breaks down for whatever reason, and you end up in a state where a actually is null, there's a bug in your program that needs fixing. The NPE that gets thrown will make that obvious

That's what I mean. Why would you rely on equals() to catch null pointers? What if you care about both b and a being null, then would you actually write:

code:
if (a.equals(b) && b.equals(a)) {
   //we really can't have a or b as null, so make sure that equals() throws on both
   //do stuff with a and b
}
I think you would never write this, and I would say that means you should never use equals() as a way of guarding against null!

I think it would be more obvious if the NPE was thrown when you actually tried to use behavior on a, or even better, write code that doesn't allow the null to enter the program flow in the wrong place (for example, when putting objects into a list and passing the list). You can also explicitly check and throw the NPE if you really want to.

Basically, here's what bothers me:
a.equals(b) doesn't operate the same with respect to null as a == b.
a.equals(b) is not symmetrical with respect to b.equals(a), whereas a == b is symmetrical with respect to b == a.

FieryBalrog fucked around with this message at 19:21 on Oct 15, 2015

FieryBalrog
Apr 7, 2010
Grimey Drawer
Ran into this issue today. A look at the spec says Java autounboxes for == up to +/- 127? Weird.

code:
        Integer i = 127;
        Integer j = 127;
        if (i == j) {
            System.out.println("i equals j");
        } else {
            System.out.println("i does not equal j");
        }

        Integer k = 128;
        Integer l = 128;
        if (k == l) {
            System.out.println("k equals l");
        } else {
            System.out.println("k does not equal l");
        }
Some guy used == in code a long time ago and it caused a lot of headaches because it worked for quite a while without anyone noticing.

FieryBalrog
Apr 7, 2010
Grimey Drawer
Generics are no joke the most fun thing I've worked with in Java.

I had a blast making stuff that would take Collection<X> and return live views of it as View<Y> using different generic transformation function inputs.

FieryBalrog
Apr 7, 2010
Grimey Drawer
Yeah I spent a ton of time writing these View and Views classes (and stuff to support them) based ultimately on Guava's FluentIterable and Function ideas.

http://hastebin.com/daleviquye.java

FieryBalrog fucked around with this message at 19:30 on Nov 2, 2015

FieryBalrog
Apr 7, 2010
Grimey Drawer
Silly question: I've heard, vaguely, that in Java 7 there's a shortcut by which I can do something like this without getting the warning:

code:
List<SomeReallyLongFuckingClassName> ints = new ArrayList(); //oh no, I omitted the generic tag here so it's warning me
Is this possible? and I don't mean "use Eclipse to insert the generic afterwards". If so, what's the syntax?

FieryBalrog
Apr 7, 2010
Grimey Drawer
^ this is a beautiful way of doing it. I had the exact same starting project (maze where a player moves around) and someone on StackOverflow pointed me to enums.

FieryBalrog
Apr 7, 2010
Grimey Drawer
I have a weird question. Today all of a sudden the Java app I'm working on stopped logging uncaught exceptions. It uses log4j. A thread that gets hit with a problem just terminates silently and it made it impossible for me to understand what was going on until I wrapped everything in try-catch blocks that caught throwable and called log.error(). It didn't matter what kind of uncaught exception, it was equally silent on SQLException and NullPointerException.

Since these were route threads in a Camel app, the app kept going but the route thread would terminate silently. It was really weird to me that the route was starting up again even though it didn't seem to have finished its prior run.

Prior to today I never saw this issue and google isn't turning up another instance of it. I don't know much about log4j except that our current setup is really overly complicated and was configured by a dev who is not really the best.

It doesn't show on the console or on the log files which are still written out to the correct directory.

FieryBalrog fucked around with this message at 02:00 on Nov 7, 2015

Adbot
ADBOT LOVES YOU

FieryBalrog
Apr 7, 2010
Grimey Drawer

baka kaba posted:

Yeah it's a unit test - basically I'm writing two different structures into a database and making sure I get the same two back, and I'm not assuming anything about the ordering so I need to match them to their appropriate source objects

There's a bit more after that (some assertions to make sure each object's related structure is correct - they each represent a different test case) which is why I'm assigning them to a variable, but I was just wondering about the matching problem really. The map idea seems like a good fit for larger collections, I was just wondering if there was a slick solution to it

The 'just use A1' thing is a good idea, but I'm checking things not covered by my equality test (they're nodes and I'm checking the tree, maybe this is a horror) which is why I want to keep the original around. Also Hamcrest is not a name I'm making friends with

Why not use Collections and do something like this
code:
Set<Object> returnSet; 
Set<Object> verificationSet;
//get the objects initialized & populated however
for (Object r : returnSet) {
  if (!verificationSet.contains(r)) {
    return false;
  }

  return true;
}
then once they are ready to check, iterate through the returnSet, ask the verificationSet if it contains that object, and exit the loop if it ever fails.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply