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
Fly
Nov 3, 2002

moral compass

NotHet posted:

Well then this becomes irritating on two levels. I guess I can sorta understand a floating point quirk in Java, but why the hell did Eclipse decide to be inconsistent and represent the value as 56.9 in it's debugger? Oh well. Thanks for the help!
Most people must readjust their expectations when using fixed precision floating point numbers, such as the IEEE 754 implementation Java has. There are rounding issues because it is impossible to represent some decimal values exactly in such floating point representations.

http://www.ibm.com/developerworks/java/library/j-jtp0114/

Adbot
ADBOT LOVES YOU

Fly
Nov 3, 2002

moral compass

Boz0r posted:

What could be wrong?
What have you already tried to do to debug it?

Fly
Nov 3, 2002

moral compass

Rocko Bonaparte posted:

That's too bad. For this case it isn't a huge issue, but if I'm crunching a bunch of stuff, then I could see it being hellish trying to cram it into a single, atomic statement.
You should be able to make some private static methods to generate any of the data that you really need. The chained constructor call must be the first thing there because there is no valid instance state to reference, and the code might try to reference instance state if any instance methods or properties were accessible before the invocation of the other constructor.

In other words, it is easy to express what you really want, so it's not really a problem.

Fly
Nov 3, 2002

moral compass

Rocko Bonaparte posted:

I have a general question about databases and Java. I'm doing something that now looks like I could do better with a database. I know of things like JDBC that provide some abstraction to a database, and I generally know of persistence frameworks that add a layer on top of that for things like retrieving information for beans. I am wondering if those frameworks would interfere with what I'm try to do, or if it's worth looking into them.

I'm iterating through daily stock data from files right now, with each symbol in a file. Every line has the symbol, date, closing price, opening price, high, low, and volume. So it's pretty much just big tables. I'd want to be able to look up spans of data for each symbol as a basic thing, but then also be able to query based on extra numeric data I'm going to provide. I suck at SQL (since I never use it after taking the tutorials) but it seems like these are pretty basic queries. So would a persistence framework on top of that be more of a burden?
I know of no persistence framework that will make it [edit]easier to write the simple or complex queries you want. Things like JPA QL or Hibernate HQL may give you basically the equivalent of SQL, and maybe if you're inserting the data with a persistence framework (e.g., JPA or Hibernate), you could use their query language to get just the data you want rather than whole objects that you would then operate upon in the JVM.

Fly fucked around with this message at 19:39 on Dec 15, 2008

Fly
Nov 3, 2002

moral compass

Rocko Bonaparte posted:

Maybe that would work for me, but I'd need to shift to J2EE to start using bean components.
I would stay far away from J2EE. The JPA stuff in the EJB 3.0 specification is nice though. It's basically a simplified version of the Hibernate APIs. You do not need to use J2EE bean stuff (session beans, entity beans, hillo beans) for anything, ever.

Fly
Nov 3, 2002

moral compass

Rocko Bonaparte posted:

Can one use Hibernate without a J2EE framework? I've only ever seen it used in J2EE.
Yes, one can use Hibernate without any J2EE stuff. There's a simple API for managing sessions and transactions that allows you to load and save your objects. I do recommend using some kind of framework to manage the sessions rather than trying to manage them in your application logic.

I am more familiar with the JPA's terminology and API, so I cannot name the Hibernate APIs from memory.

Fly
Nov 3, 2002

moral compass

rjmccall posted:

This is usually true, but it breaks down when you want to simultaneously generate multiple values to pass to a different constructor. For that you'll have to either 1) build some sort of temporary tuple object (the construction of which probably won't be optimized out, if you're performance-obsessed) or 2) use a static builder method (which of course can't be used by subclass constructors). Java is unnecessarily restrictive here; the JVM itself is more permissive but still does not allow loops before delegate constructor calls.
The tuple object pattern is what I would typically use as a solution. It is an annoyance more than an problem.

Fly
Nov 3, 2002

moral compass

Fehler posted:

Does anybody know where I could find sample code for comparing two WAV audio streams in Java? I need a function that returns some kind of "score" telling me how well the two streams match. From what I found on Google it looks like I need to do a Fourier Transformation, but I'm not really sure how to implement that and how to use it.
I would start reading about Fourier transforms. They convert a time-domain signal, such as a PCM (pulse-code-modulation) signal, into the frequency domain. You may also want to look at transforms like the Modified Discrete Cosine Transform (MDCT) which do about the same thing, but may be more useful as you may find more examples of other transforms used by, say MP3 or OGG Vorbis codecs.

Once you transform the WAV, you can compare the frequencies present over time, probably vaguely similarly to the way you would compare strings in a string search algorithm that allowed for some inexactness.

There's an iPhone and Android app that does this and tells you what song you are sampling with the phone's microphone.

Fly
Nov 3, 2002

moral compass

firetech posted:

QUESTION:
I'm using Gregory Guerin's AuthKit to 'authenticate' (a.k.a. run with elevated privileges) my new java application in Mac OS X. I cannot figure out how to authenticate the currently running app though. All I can do is launch another jar file with elevated privs. Is there a way to privilege the currently running java app?
Are you asking how to make your application run with elevated privileges when your application starts, or are you wanting to change the privileges of an already-running application? The former is accomplished by signing your code, etc.. The former is not really possible unless you had started your code with an AccessControlContext that has some special ProtectionDomain to which you retain a reference and you alter at runtime.

edit: Probably nevermind what I wrote. Authkit seems to have little to do with Java security but instead with Mac OS X security, i.e., running with root privileges.

Fly fucked around with this message at 05:16 on Jan 1, 2009

Fly
Nov 3, 2002

moral compass
I asked someone to write a Person.equals() method and got this code, which will arbitrarily break in some cases if a person is born an January 31, 2010.
code:
public boolean equals(Object o) {
    boolean retVal = false;

    // often good to use
    if (this == o)
      return true;
    if (!(o instanceof Person))
      return false;
    Person otherPerson = (Person) o;
    String aFirstName = otherPerson.getFirstName();
    String aMidName = otherPerson.getMiddeName();
    String aLastName =  otherPerson.getLastName();
    Date aDate = otherPerson.getBirthDate();
    String thisFirstName = this.getFirstName();
    String thisMidName = this.getMiddeName();
    String thisLastName =  this.getLastName();
    Date thisDate = this.getBirthDate();

    if (aDate == null) aDate = java.util.Date.valueOf( "2010-01-31" );
    if (thisDate == null) thisDate = java.util.Date.valueOf( "2010-01-31" );
    if (thisFirstName.compareToIgnoreCase(aFirstName)==0 &&
	thisMidName.compareToIgnoreCase(aMidName)==0 &&
	thisLastName.compareToIgnoreCase(aLastName)==0 &&
	thisDate.compareTo(aDate)==0)
	retVal = true;

   return retVal
  }
Is there some reason a person would pick 2010-01-31 as substitute for null? Is this from some horrible PHP/J2EE/etc. practice with which I am not familiar?
Ignore the stylistic problems for now.

Fly
Nov 3, 2002

moral compass

HFX posted:

I will say they are dumb. There is actually quite a bit in that code I find questionable.
Other questions I asked had answers cut and pasted directly from places like Stackoverflow.com. :ughh: I just wonder where he cribbed that particular wrong answer.

Fly
Nov 3, 2002

moral compass

DholmbladRU posted:

I am posting here because java is the language which is most fimiliar to me.

I have been asked by my campus job to think about how to extract data from an excel spreadsheet. I figure I can probably write a simple java program. All of the columns are static(or Ill tell them they have to be). And I only need to be able to search on a few fields. My question is, how can I go about outputting an excel file.
You do not want to parse an Excel spreadsheet on your own. The file format for Excel 97 (common still) basically contains it's own mini-FAT file system, which was probably very useful when computers could not hold the entire file in RAM, but now makes handling the file rather difficult.

Jexcel is pretty good, but there is also the Apache POI project, which might be okay. POI used about 10x the memory that Jexcel did when I evaluated them years ago (2004), but the developers may have fixed some things since then.

edit: It may be a lot easier to deal with CSV files if you can control how the data is exported from Excel. Otherwise, Jexcel is pretty easy to use.

Fly fucked around with this message at 17:47 on Oct 7, 2009

Fly
Nov 3, 2002

moral compass

rhag posted:

I have personally used Apache POI (http://poi.apache.org/) for both writing and reading excel files (last time I used them was 6 months ago) , and I was very pleased with the result.
Haven't used JExcel yet, but I will certainly give it a try next time I have to produce an excel report from a java application (being it web or desktop).
Have you tried using POI to write a 1 million cell spreadsheet? Did it work without generating an OOM (even with a 1GB heap) and taking forever? That was one of the failure modes we saw, and I would be happy to know whether it has been fixed.

Fly
Nov 3, 2002

moral compass

Parantumaton posted:

POI is designed to be one of those API:s which build everything in memory and then dump the final result into wherever you direct it to dump so no, any POI API -inluding HSSF - will most likely never allow you to use it for massive spreadsheets etc.
Building the spreadsheet in memory is true of Jexcel as well, but POI managed to use about ten times as much memory as Jexcel to build the same spreadsheet, which more severely limited the usefulness of POI. I think some of the memory issues may have been addressed, but I have never had a reason to reevaluate our Excel generation library.

Fly
Nov 3, 2002

moral compass

dis astranagant posted:

e: switching from writeChars to writeUTF almost fixes it, except for 2 extraneous bytes at the start of the body that make no sense and aren't in the original string. No clue what's going on with the byte array output, though.
Could that be a byte-order mark (BOM)? http://unicode.org/faq/utf_bom.html#BOM

Fly
Nov 3, 2002

moral compass

1337JiveTurkey posted:

It's the length of the encoded string in bytes.
Thanks. Obviously I would know this had I bothered to look at the on-line Javadoc for DataOutputStream.writeUTF().

Fly
Nov 3, 2002

moral compass

yatagan posted:

code:
ArrayList<String> someStringList = new ArrayList<String>();
while (iterationOverUnknownSize) {
	someStringList.add(someString);
}
return new MethodThatOnlyTakesStringArrays(someStringList.toArray(new String[0]));
I think it's nicer to use a more expressive syntax:
code:
return new ArrayList<String>() {{
    for (String someString : someArrayOrCollectionOfStrings) {
      add(someString);
    }
  }}.toArray(new String[0]);
Creating your extra String[0] is trivially cheap. The someArrayOrCollectionOfStrings has to be a member variable or final so the closure will work, but that's good (more functional) style, too.

Fly
Nov 3, 2002

moral compass

funkatron3000 posted:

I have a slightly challenging design problem, looking for second opinions...

Given
1) A slow InputStream with an arbitrarily large unknown amount of data (up to several gigabytes)
2) A vertically scrolling viewer that swaps in chunks of data from the InputStream as requested by the user
3) Enough disk space to cache everything, but we want to minimize its use.

So... I figure I need some kind of caching mechanism between the InputStream and the viewer to provide random access, if not per character, at least by some arbitrarily sized chunk.

The best idea I've been able to come up with is some kind of two file solution. One index file that maps offsets of chunks from the stream to offsets in a second file containing the data. Chunks of data would be written to the file as requested by the user by scrolling. So you'd ask the index file where bytes 50k - 55k are, if they don't exist then seek in the InputStream and write the data to the data file and update the index, otherwise read from its existing location in the data file.

Does anyone know of a better way to tackle this? Or know of any existing packages/design patterns?
If you want to give the user random access to the file, I think you'll need to store it all as a local file and just use something like FileInputStream.skip(n) and reset() to move through the data, if you need to allow the user completely random access because you don't want to cache Gigabytes of data in the JVM heap.

Fly
Nov 3, 2002

moral compass

Mustach posted:

This makes me :barf:. Initializing an array is not worth having an entire class definition sitting around in your jar.
That is a fair point. It adds 546 bytes (uncompressed) to the jar to have the extra .class, and that can add up. I am not sure how much overhead is needed by the JVM, but I assume it won't matter in most cases as the class definitions get garbage collected.

Fly
Nov 3, 2002

moral compass

Kilson posted:

I know exactly which line of my code that's the last one to be executed. Beyond that, it goes into a third-party jar to do some axis communication. That still leaves me questioning exactly how this can cause my problem.
My first guess is that your third party code may be hanging, though if you say it is skipped, then that indicates you have something else later confirming that the thread is running (another log statement somewhere?).

If it is hanging, then you can create a thread stack dump (`kill -QUIT <pid>` on Linux/Unix) to see why that thread is waiting.

Fly
Nov 3, 2002

moral compass

Kilson posted:

You are correct. If there's an exception thrown in doThing1(), I'm not expecing doThing2() to be executed. I'm expecting the exception to be caught where it should be caught, and for execution of the main method to continue.

The problem is that even with catch(Throwable t), there's nothing being caught. The execution simply stops. Furthermore, anything in the main method AFTER the try/catch block is also not getting executed.

As I said, it makes no sense whatsoever, which is why I'm asking if anyone has ever seen anything like it, or has any ideas of what I can try.

(I haven't had a chance to seriously try the debugger yet, been working on on-site interop testing all week :puke:)
If it is stopping and not exiting, just take a thread dump and see what's going on. Post the (relevant portions of the) thread dump if you would like us to take a look.

edit: or install VisualVM from Sun and see what's going on. http://java.sun.com/javase/6/docs/technotes/guides/visualvm/index.html

Fly
Nov 3, 2002

moral compass

Kilson posted:

It doesn't stop or exit, it just continues running (after skipping whatever code it skips) as if nothing ever happened.
Do you have some logging that indicates it is still running? Can you post the code that supports your observation?

Fly
Nov 3, 2002

moral compass

Brain Candy posted:

Hell, if you only use List for iteration, just use Collection.
Collection is only an interface, so it does not really address the question of which type to instantiate.

Fly
Nov 3, 2002

moral compass

Brain Candy posted:

Hmm, that is a little unclear. Second time's the charm : if you only use the List interface for .iterator() you could just store/pass/return things as Collections or Iterables instead.

edit: ^^^ ha, apparently I wasn't completely unintelligible
Yes, I agree entirely then. :)

Fly
Nov 3, 2002

moral compass

Parantumaton posted:

To be specific, the reason I'm asking is that I need to sort a list containing about several hundred objects. The related comparison math is rather heavy and overcomplicated and while I can cache parts of it manually, it can't be cached fully because the comparison object alters the the result itself significantly; it's not just "is x bigger than y?" comparison.
Do you mean the comparator, when you write "the comparison object"? Are you saying the act of compare(o1, o2) modified o1 or o2 in a way other than, say, lazy-loading contained objects from persistence?

Fly
Nov 3, 2002

moral compass

Parantumaton posted:

Yes, it's part of a really finicky and code-smellish set relevance comparison.
If your comparator changes the result of the next call of the comparator on the same objects, then the Java sorting methods probably won't work at all.

Fly
Nov 3, 2002

moral compass

wintermuteCF posted:

code:
System Variables:
CLASSPATH: c:\program files\java\jdk1.6.0_17\lib;c:\program files\java\jdk1.6.0_17\bin;
C:\Program Files (x86)\QuickTime\QTSystem\QTJava.zip
Javac generally does not need the jdk jar files in it's classpath, and I don't think setting the classpath to the directory where the jar files are will help at all.

If you change your classpath only to include the QTJava.zip file, does that help?

Fly
Nov 3, 2002

moral compass

MEAT TREAT posted:

Compiling from the command line is loving annoying. I suggest you use an IDE or learn to use Ant/Maven to do your compiling for you.
Are you suggesting this for the HelloApp.java issue above?

Fly
Nov 3, 2002

moral compass

RichardA posted:

A subclass can not access anything in a super class simply because it is a subclass. It gets its own entirely separate copy of the fields.
Would you explain what you mean by this because I am not sure what you are claiming?

Fly
Nov 3, 2002

moral compass

RichardA posted:

Mulloy said "The array object is declared in the first class. The second does not declare it, and it renders the information in the array.". This, along with the lack of a Engine instance or a aGrid reference being passed to TwoWindows in the posted code, left me with the impression that Mulloy may not have a good understanding of classes and thinking that a instance of TwoWindows has access to WindowOpener fields; i.e. that aGrid in TwoWindows will be a reference to the same aGrid in WindowOpener.(I know considering how classes can have more than one instance will reveal how nonsensical that is but I have seen someone make this mistake before)
I don't see how you get that from the posted code.

quote:

By its own copy I meant that state that while a subclasses inherited fields have the same name and type as the fields of the superclass, they are separate variables. Copy was a poor chose of word to use.
I still do not know what you're trying to state. The only nonlocal variable is aGrid, so there is only one instance of a Grid in his code, and it's on the Engine class. It is bad style, and may not be what he wants, but there are not separate aGrid variables for the different classes, just one, and only one---Engine.aGrid.

Fly
Nov 3, 2002

moral compass
Use finally to close resources.
code:
Connection foo = null;
try {
  foo = getConnection();
  // stuff
}
catch () {
  // stuff
}
finally {
   if (foo != null)
       foo.close();
}
Be sure to close your Statements, too. edit: Also be sure your finally is not throwing exceptions when you are closing multiple things, but if you close the Connection, you're closing the ResultSet.
code:
finally {
  try {
    if (rs != null)
      rs.close();
  } catch (Exception ex) { // waaah }
  finally {
    if (foo != null)
      foo.close();
  }
}
You can write a safeClose(ResultSet rs) that catches the exception if you have to repeat this pattern a lot.

Fly fucked around with this message at 07:01 on Dec 7, 2009

Fly
Nov 3, 2002

moral compass

TRex EaterofCars posted:

WeakReference is your friend.
That could be a bad idea though. If the jobs have not been completed, but they are only weakly reachable, the garbage collector could get rid of them before they are executed. In the case of a work queue, I suggest a producer/consumer model for most situations.

Fly
Nov 3, 2002

moral compass

Lysidas posted:

I'm under the impression that in Java*, exception handling is slow compared to conditional statements and that it is not intended to be part of the normal flow of program execution.

In general, you should only throw and expect to catch an exception if something ... exceptional happens. If having a null value in your collection is normal and common, don't write code as if it won't happen and catch the NullPointerException.


*Silly Python with its StopIteration exceptions. I kid; I love Python and think that this is a perfectly reasonable way to implement something like this, especially if exception handling is designed to be fast enough for this to be feasible.
Correct. The last time I tested this, throwing an exception was at least two orders of magnitude slower than using a conditional. Sometimes a 100x slowdown does not matter. However, the slow part is generally creating a new Throwable since the JVM has to figure out the stack, so if you throw an existing Throwable, or a singleton instance of one, it won't be so bad, and you could do that very easily when the exception does not originate from an exceptional condition. It's still not idiomatic Java style, so I would avoid it.

Fly
Nov 3, 2002

moral compass

FateFree posted:

Can anyone give me some insight to how the best way to architect this may be? Even if its not a solution, some direction might help clarify things for me.
You might want to look at using Annotations, such as the javax.persistence.* annotations for Entity classes, which are the things you are loading via your DAO. The GenericDao can lookup the mapping of database fields to object properties using the Column annotation. You don't have to do an implementation of the Java Persistence Architecture but only use the useful annotations. This allows you to avoid creating a whole separate hierarchy of classes that mirrors your data object hierarchy.

Fly
Nov 3, 2002

moral compass
I like the language specification: http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html

Fly
Nov 3, 2002

moral compass

geeves posted:

Not a specific code question

When are the best times to synchronize? It seems like the logical choice is for when transactions occur (adding / modifying database or repository).

But are there other times when synchronization becomes crucial? Or should it be kept to the minimum?
You need to synchronize whenever you modify the representation of an object in a non-atomic way if that object can be accessed by other threads.

The synchronization locking must not be more fine-grained than the represented data.

code:
// Representation invariant: balance cannot be negative
private BigDecimal balance;

public synchronized void deposit(BigDecimal amt)
{
    balance = balance.add(amt);
}

public synchronized void withdraw(BigDecimal amt)
{
    BigDecimal after = balance.subtract(amt);
    if (after.signum() >= 0) {
        balance = after;
    }
    else {
        throw new OverdraftException(after);
    }
}

public BigDecimal getBalance()
{
    return balance;
}
The deposit and withdraw methods must be synchronized at least on the balance object. I am synchronizing on the containing object for simplicity. If we did not synchronize, then two threads modifying the object via any combination of deposit() and withdraw() could invalidate the representation (i.e., the value of balance).

The getBalance() method does not cause any change to the value of balance, and because the object assignment that occurs in deposit() and withdraw() is atomic, getBalance() does not need to be synchronized.

The race condition that could invalidate the balance occurs because in deposit() and withdraw() we are both checking or getting the value of balance before using it to calculate the new balance. If one thread is processing the bytecodes for deposit() or withdraw(), and another thread is doing the same simultaneously owing to thread preemption or parallel processing, the values on the stack for balance that the first thread sees would be wrong, and the resulting value would be wrong.

E.g.,

It can work sometimes if the sequence of operations performed by the JVM is "just right" resulting in the correct value of $16 for balance:
  1. The balance starts at $4.
  2. Thread 1 calls deposit($5).
  3. Thread 2 calls deposit($6).
  4. Thread 1 reads a value of $4 for balance.
  5. Thread 1 adds $5 to $4 to yield a new value of $9.
  6. Thread 1 assigns $9 to balance.
  7. Thread 2 reads a value of $9 for balance.
  8. Thread 2 adds $6 to $9 to yield a new value of $16.
  9. Thread 2 assigns $16 to balance.
However, because the operations of Thread 1 and Thread 2 could be interleaved in any possible way so long as the operations of Thread 1 maintain their overall order, and the operations of Thread 2 maintain their overall order, the JVM could process them like this resulting in a wrong value of $10 in balance:
  1. The balance starts at $4.
  2. Thread 1 calls deposit($5).
  3. Thread 2 calls deposit($6).
  4. Thread 1 reads a value of $4 for balance.
  5. Thread 2 reads a value of $4 for balance.
  6. Thread 2 adds $6 to $4 to yield a new value of $10.
  7. Thread 1 adds $5 to $4 to yield a new value of $9.
  8. Thread 1 assigns $9 to balance.
  9. Thread 2 assigns $10 to balance.
You could interleave the thread operations in other ways to generate other incorrect values, and you could call the withdraw() method as well to make it more complicated. The getBalance() method does not really care which version of balance it sees only because my example never assigns an intermediate value to balance. If I wrote the withdraw() method as follows, then getBalance() would also need to be syncrhonized:
code:
public synchronized void withdraw(BigDecimal amt)
{
    balance = balance.subtract(amt); // Assigning an possibly invalid value!
    if (balance.signum() < 0) {
        // getBalance() called now returns an invalid value.
        balance = balance.add(amt); // Change the value back.
        throw new OverdraftException(balance.subtract(amt));
    }
}
Calling an unsynchronized getBalance() can return an intermediate value that never represented a real value of balance because it may violate the representation invariant of never being negative. Code using this class should be able to depend on the representation invariant, so it might fail in unexpected or unnoticed ways.

This example assumes that all of the values are stored on the JVM stack and read from a single copy of the data in the JVM's memory, but the JVM memory model also allows each thread to have its own copy of parts of memory, so it gets even worse unless you syncrhonize. In addition to getting a lock on an object, synchronization causes the thread to flush its own copy of memory and read from the "real" memory.

edit: spelling and grammar

Fly fucked around with this message at 17:26 on Jan 15, 2010

Fly
Nov 3, 2002

moral compass
GregNorc, keep in mind that

(6209 ^ 5) - ((2 ^ 63) - 1) = 4643121256274242

while

(6208 ^ 5) - ((2 ^ 63) - 1) = -2785645994967039


You don't want to loop to Long.MAX_VALUE.

Fly
Nov 3, 2002

moral compass

GregNorc posted:


A:1 B:1 C:1 D:2 E: 1

A:1 B:1 C:2 D:1 E: 1

... I think you get the drift
These are effectively the same condition, and it's pointless to duplicate effort that way. You only need to check permutations and not combinations. You can generate the possible combinations of a, b, c, and d from the permutations once you have them.

Fly
Nov 3, 2002

moral compass

epswing posted:

Assuming "lookup" means retrieving a value based on a key, does Map.Entry magically obtain a value without a lookup?
When iterating over a HashMap's entrySet, there is no hash lookup done at all. The entry objects contain the key and value references so retrieving the key and value are simple accessor methods on the Entry object.

Adbot
ADBOT LOVES YOU

Fly
Nov 3, 2002

moral compass

Parantumaton posted:

One gotcha I'd like to mention, Entry contains apparently only weak references to the key and value it holds...
This is only true for WeakHashMap and not HashMap, but the programmer should generally not depend on either one being in use. The HashMap.Entry class uses regular strong references to hold both the key and value:
code:
// java.util.HashMap.java (JDK 1.6.0_10)
    static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        final int hash;
The WeakHashMap.Entry class uses a WeakReference only for the key:
code:
// java.util.WeakHashMap.java (JDK 1.6.0_10)
    private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> {
        private V value;
        private final int hash;
        private Entry<K,V> next;
It is just as possible that a key would become null within the loop as well:
code:
for(Entry<Key, Value> entry : someMap.entrySet()) {
    // getKey() may be null already, so this is not safe.
    if (entry.getKey().equals(somethingOrRather)) {
        // getKey() may be null now if it was not already.
        doSomething(entry.getKey());
        break;
    }
}
If you may be using a WeakHashMap I think you have to watch out in any case because entry.getKey() might begin returning null at any point.

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