Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to learn design patterns as good coding practices and I would like to know if a HashSet is considered a well-written class? eg:
To construct a LinkedHashSet we use the following constructor
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
Which calls this one:
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
So there is a useless param, is it correct to do that?
Also, I see that LinkedHashSet extends HashSet
LinkedHashSet<E> extends HashSet
and HashSet references LinkedHashSet in its code, why there is nothing like a compile time recursion there?
// Create backing HashMap
map = (((HashSet<?>)this) instanceof LinkedHashSet ?
new LinkedHashMap<E,Object>(capacity, loadFactor) :
new HashMap<E,Object>(capacity, loadFactor));
This is severely optinion based.
And in a lot of situations, the programmers had to make hard choices. And there has been so many teams at work, that it's natural that some of the following problems occur.
However, here's my opinion on that topic:
Most of the JDK code is a mess. Unnecessary code, convoluted code that modern Java JIT compilers easily will do better
There's lots of micro optimizations, but in the end a lot of implementations can rewritten to be much faster, cleaner, more compatible.
Simple classes like ArrayList are already a mess, and if you write your own implementation, it will be twice as fast.
The Input/OuputStream system is a mess, should have had an interface at the very top.
A lot of solutions like ThreadLocal are inherently unsafe to use and can cause leaks if not worse problems.
There's a lot of repetition of code where there shouldn't be
a huge lacking support for default conversions, especially String to something else, should have default methods like s.toInt(int default)-like methods
The java.util. functions and FunctionalInterfaces are a mess, with lots of different names that could have been constructed in a far more logical and intuitive way, alsong with all the Collectors and stuff. Could be so much easier.
On the other hand:
The Collections structures (inheritance, Interfaces etc) are over all pretty well implemented, with only very few features missing
the java.nio stuff is really good
The Exceptions (RuntimeException, Throwable) hierarchies are quite good and provide a stable basis for additional custom classes (that one might prefer to / should use)
Some aspects that to not target the implementation of classes, but the language specification:
how they introduced and integrated Lambdas and Streams (the whole functional show)
Generics and Covariance/Contravariance
Reflection and Annotations
All in all, if you give your default Java a little boost with libraries like Project Lombok (adding AOP and stuff), it is awesome. I really love it, and so far no other language could un-favorite Java (even tho I hated Java when I had to learn it)
So, as others have stated:
learn from the code (some techniques are REALLY good)
improve upon them (some are obviously BAD)
And finally to the points you addressed:
The dummy parameter. This is a very rare occurrence, and even then mostly only occurs for quality-of-life: instead of having only one CTOR with 3 arguments, also have another CTOR with 2 arguments
concerning the compile time recursion: Java compiler can be compared to a multi-pass compiler, so the 'recursion' does not play a role. What is a little bad about this implementation - a very theoretical/academic complaint - is that HashSet and LinkedHashSet are now statically bound in BOTH directions. LinkedHashSet -> HashSet would be fine (how else would inheritance be implemented!?), but HashSet -> LinkedHashSet is a bit of a bugger. But, well, academic, because those two classes are in the same package, and not even the new Modules system will rip them apart. So unless you write a packaging tool that discerns on such a low level (like I did), this point has no practical impact.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm looking for the best way to implement three-valued logic.
I googled and found three different approaches:
Use null value for Boolean variable as undefined
This variant looks to dangerous for me because it can unexpectedly cause NullPointerException
Use Optional<Boolean> type
This variant still is a bit dangerous. To avoid NoSuchElementException you should use constructions like this:
Optional<Boolean> amIRight = Optional.empty();
if (Optional.of(true).equals(amIRight ) {
doSome();
}
It looks too wordy for me
Implement your own enum
The last variant seems to be the best. Almost safe, very simple in undefstanding. But I haven't find any of such enums in widely spread java libriaries such as Apache, Google Guava and so on. It looks strange for me everybody avoids the simpler and safest implementation.
May be I missed something and there are serious reason not to implement three-valued logic enum.
If enum works for you, go for it.
Don't use that Boolean, it is ugly and destroy readability ... I also can't imagine how horrible it would be if you want it to support 4 values later...
Other cautions / advise :
Are you sure that you will use only 3 values?
In many situation, design tends to change, and enum will be no longer enough.
Using a class that encapsulate enum (or int) can provide better flexibility.
However, you can change from enum to class later.
In my program, I extensively use enum.
You shouldn't care much about what popular libraries do, just pick the best that work for you!
About the very interesting hypothesis :
... there are serious reason not to implement three-valued logic enum. ...
Suppose that I am Java language designer.
You ask for a 3-logic enum.
I accept you proposal.
Then, Mr.2D ask "We have 3-logic enum. Why don't you provide 4-logic enum to support +x -x +y -y?".
I give him what he want.
After that, Mr.LoveFive Mr.ObsessiveSick ..... I think you got the point.
There has to be a threshold (when to stop) and the demand for 3-enum is relatively very low compared to 2-enum (boolean).
I agree that enums is by far the safest and best solution to your problem. Perhaps enums are not widely used in projects like Apache because enums are relatively new in Java (I think they came along in Java 1.5).
If you want 3 valued logic, you are no longer talking about simple true/false conditions, you are talking about a state machine. Arguably state machines are among the most powerful paradigms in programming. If you aren't conversant with automata theory, look it up.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've seen some legacy code that uses lengthproperty on some objects and others that uses length() method. Currently I'm working with a NodeList from the org.w3c.dom package and I found that it have the getLength() method to get the numbers of elements.
My Question is how as Java developer I can know how to determine when to use length, length(), size(), getLength()? obviously it depends of the object type and the API is there for read... but the point is how the Java Development select which of that implements in their classes.
Note: In the Question When to use .length vs .length() Makoto answer's indicates that .length is a property on arrays. That isn't a method call, and length() is a method call on String. But, why is the reason? why not use ever a method or ever a property for maintain the consistency around all the API.
how would Java developers select which of [the methods] to implement in their classes?
When you implement classes that contain other objects, it's almost always going to be size(), the method provided by theCollection interface.
As far as other choices go, you should avoid exposing member variables, even final ones, because they cannot be accessed through an interface. Java gets away with it for arrays because of some JVM trickery, but you cannot do the same. Hence, length should be out: it remains in Java because it's not possible to change something that fundamental that has been in the language from day one, but it's definitely not something one should consider when designing new classes.
When you implement your own type that has length (say, a rectangle or a line segment) you should prefer getLength() to length() because of Java Beans naming conventions.
obviously it depends of the object type and the API is there for read...
You already have answered your question yourself: look in the API documentation of whatever class you are using.
but the point is how the Java Development select which of that implements in their classes.
The classes in Java's standard library have been developed over a long period of time by different people, which do not always make the same choice for the name of methods, so there are inconsistencies and unfortunately you'll just have to live with that.
There is no clear rule, otherwise we wouldn't see such a mixup in the jdk itself. But here are some things to consider when making such a design decision.
Don't worry to much. It is a minor thing and won't make to much of a difference. So when you think longer then 5 minutes about this, you are probably wasting money already.
Use getters when a frameworks need them. Many frameworks depend on the getter style. If you need or want such frameworks to work nicely with your class it might be beneficial to use that style.
Shorter is better. the 'get' part doesn't increase clarity. It just generates to characters of noise to the source code, so if you don't need it for some reason, don't use it.
Methods are easier to evolve. Length is often a quantity that is not set directly but somehow computed. If you hide that behind a method it gives you the flexibility to change that implementation later on, without changing the API.
Direct field accesses should be a tiny bit faster, but if you aren't working on high volume online trading or something, the difference isn't even worth thinking about. And if you do you should do your own measurements before making a decision. The hotspot compiler will almost for sure inline the method call anyways.
So if there aren't any external forces driving you in a different direction I would go with 'length()'
According to OOPS principles, length should be attribute and getLength() should be method. Also length attribute should be encapsulated should be exposed through methods, so getLength() sounds more appropriate.
Unfortunately not all Java library classes follow standards. There are some exceptions and this is one among them.
In a pure OO language it should be probably always a method like length(). So in a class hierarchy you can override the attribute length.
But Java is not pure OO. And the main reason for fields (.length) vs method (length()) is/was performance issues.
And even Sun/Oracle programmers did some bad class design.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have been studying a bit of Java and C++ more or less at the same time and I noticed that Java has a more friendly and intuitive way of interpreting the OOP than the C++ way.
Yes, Java is completely OO and, on the other hand, C++ supports many paradigms, but this doesn't mean that C++ couldn't improve its way of implementing the OO paradigm.
C++ supports multiple inheritance and Java translated it with multiple implementation (interfaces), which I find really intuitive and simple (I don't think that this is just an opinion).
My first question is in the title. I think that C++ would be more friendly, without losing practically a bit of its power. It's a question of improving a extraordinary programming language, which however is not perfect.
My second question is: what are the advantages of multiple inheritance compared to the interfaces of Java programming language (if any)?
Multiple inheritance can be dangerous, but it's sometimes the most appropriate solution to a problem, and there's lots of software already written that uses it. Removing multiple inheritance from C++ would break all that software, in a way that's not simple to fix. Being compatible with existing code is more important than being "friendly".
If you want the effect of a Java interface in C++, just write a class that contains nothing but pure-virtual member functions, and derive from it using virtual inheritance to "implement" it in another class.
Java was designed as a higher-level and simpler language than C++, and the tradeoffs between them are the same as between any high-level and lower-level language. Java provides a bit less flexibility (e.g. single inheritance, little control over memory allocation) in exchange for being a bit easier to work with; C++ provides more power and flexibility at the cost of having to "know what you're doing" a bit more. These differences are OK; there's no need to turn one language into the other.
C++ is becoming more and more user-friendly with the updates, becoming bit by bit more like java, but it needs not to change too much not to wreck legacy code. The Boost library is more or less the pioneer of the c++ language, being the (probably) most used library of all times and taking an easier and more intuitive OO approach to c++. Features from the Boost libraries often get to the STD eventually.
Let's take this easy example : class man and class parent have respective functions work and cry. class dad inherits from both man and parent. Now you don't have to write cry twice when you write class mom which inherits from class woman as well as from parent.
1.Having multiple inheritance in a explicit way is seems to be more user friendly but actually it is not. There are lot of problem will be coming in the future if you do that i mean in your project for an instance knowingly unknowingly you will be adding the same code again and again to your final Class which makes your project more complicated and confuses the interpreter which method should be executed at the appropriate time.
Just consider in C++ you have
Class A
{
void display_a(){}
}
Class B A
{
void display_b(){}//this class contains 'display_a()' too
}
Class C A,B //multiple inheritance.
{
display_c(){} //this class contains two times 'display_a()' and one time 'display_b()'
}
so class a contains two times 'display_a()' this is the problem we have in multiple inheritance in C++ so that we go for Interface in Java,which solve that problem.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am keen to look into Scala, and have one basic question I cant seem to find an answer to:
in general, is there a difference in performance and usage of memory between Scala and Java?
Scala makes it very easy to use enormous amounts of memory without realizing it. This is usually very powerful, but occasionally can be annoying. For example, suppose you have an array of strings (called array), and a map from those strings to files (called mapping). Suppose you want to get all files that are in the map and come from strings of length greater than two. In Java, you might
int n = 0;
for (String s: array) {
if (s.length > 2 && mapping.containsKey(s)) n++;
}
String[] bigEnough = new String[n];
n = 0;
for (String s: array) {
if (s.length <= 2) continue;
bigEnough[n++] = mapping.get(s);
}
Whew! Hard work. In Scala, the most compact way to do the same thing is:
val bigEnough = array.filter(_.length > 2).flatMap(mapping.get)
Easy! But, unless you're fairly familiar with how the collections work, what you might not realize is that this way of doing this created an extra intermediate array (with filter), and an extra object for every element of the array (with mapping.get, which returns an option). It also creates two function objects (one for the filter and one for the flatMap), though that is rarely a major issue since function objects are small.
So basically, the memory usage is, at a primitive level, the same. But Scala's libraries have many powerful methods that let you create enormous numbers of (usually short-lived) objects very easily. The garbage collector is usually pretty good with that kind of garbage, but if you go in completely oblivious to what memory is being used, you'll probably run into trouble sooner in Scala than Java.
Note that the Computer Languages Benchmark Game Scala code is written in a rather Java-like style in order to get Java-like performance, and thus has Java-like memory usage. You can do this in Scala: if you write your code to look like high-performance Java code, it will be high-performance Scala code. (You may be able to write it in a more idiomatic Scala style and still get good performance, but it depends on the specifics.)
I should add that per amount of time spent programming, my Scala code is usually faster than my Java code since in Scala I can get the tedious not-performance-critical parts done with less effort, and spend more of my attention optimizing the algorithms and code for the performance-critical parts.
I'm a new user, so I'm not able to add a comment to Rex Kerr's answer above (allowing new users to "answer" but not "comment" is a very odd rule btw).
I signed up simply to respond to the "phew, Java is so verbose and such hard work" insinuation of Rex's popular answer above. While you can of course write more concise Scala code, the Java example given is clearly bloated. Most Java developers would code something like this:
List<String> bigEnough = new ArrayList<String>();
for(String s : array) {
if(s.length() > 2 && mapping.get(s) != null) {
bigEnough.add(mapping.get(s));
}
}
And of course, if we are going to pretend that Eclipse doesn't do most of the actual typing for you and that every character saved really makes you a better programmer, then you could code this:
List b=new ArrayList();
for(String s:array)
if(s.length()>2 && mapping.get(s) != null) b.add(mapping.get(s));
Now not only did I save the time it took me to type full variable names and curly braces (freeing me to spend 5 more seconds to think deep algorithmic thoughts), but I can also enter my code in obfuscation contests and potentially earn extra cash for the holidays.
Write your Scala like Java, and you can expect almost identical bytecode to be emitted - with almost identical metrics.
Write it more "idiomatically", with immutable objects and higher order functions, and it'll be a bit slower and a bit larger. The one exception to this rule-of-thumb is when using generic objects in which the type params use the #specialised annotation, this'll create even larger bytecode that can outpace Java's performance by avoiding boxing/unboxing.
Also worth mentioning is the fact that more memory / less speed is an inevitable trade-off when writing code that can be run in parallel. Idiomatic Scala code is far more declarative in nature than typical Java code, and is often a mere 4 characters (.par) away from being fully parallel.
So if
Scala code takes 1.25x longer than Java code in a single thread
It can be easily split across 4 cores (now common even in laptops)
for a parallel run time of (1.24 / 4 =) 0.3125x the original Java
Would you then say that the Scala code is now comparatively 25% slower, or 3x faster?
The correct answer depends on exactly how you define "performance" :)
Computer Language Benchmarks Game:
Speed test java/scala 1.71/2.25
Memory test java/scala 66.55/80.81
So, this benchmarks say that java is 24% faster and scala uses 21% more memory.
All-in-all it's no big deal and should not matter in real world apps, where most of the time is consumed by database and network.
Bottom line: If Scala makes you and your team (and people taking project over when you leave) more productive, then you should go for it.
Others have answered this question with respect to tight loops although there seems to be an obvious performance difference between Rex Kerr's examples that I have commented on.
This answer is really targeted at people who might investigate a need for tight-loop optimisation as design flaw.
I am relatively new to Scala (about a year or so) but the feel of it, thus far, is that it allows you to defer many aspects of design, implementation and execution relatively easily (with enough background reading and experimentation :)
Deferred Design Features:
Abstract Types
Explicitly Typed Self References
Views
Mixins
Deferred Implementation Features:
Variance Annotations
Compound Types
Local Type Inference
Deferred Execution Features: (sorry, no links)
Thread-safe lazy values
Pass-by-name
Monadic stuff
These features, to me, are the ones that help us to tread the path to fast, tight applications.
Rex Kerr's examples differ in what aspects of execution are deferred. In the Java example, allocation of memory is deferred until it's size is calculated where the Scala example defers the mapping lookup. To me, they seem like completely different algorithms.
Here's what I think is more of an apples to apples equivalent for his Java example:
val bigEnough = array.collect({
case k: String if k.length > 2 && mapping.contains(k) => mapping(k)
})
No intermediary collections, no Option instances etc.
This also preserves the collection type so bigEnough's type is Array[File] - Array's collect implementation will probably be doing something along the lines of what Mr Kerr's Java code does.
The deferred design features I listed above would also allow Scala's collection API developers to implement that fast Array-specific collect implementation in future releases without breaking the API. This is what I'm referring to with treading the path to speed.
Also:
val bigEnough = array.withFilter(_.length > 2).flatMap(mapping.get)
The withFilter method that I've used here instead of filter fixes the intermediate collection problem but there is still the Option instance issue.
One example of simple execution speed in Scala is with logging.
In Java we might write something like:
if (logger.isDebugEnabled())
logger.debug("trace");
In Scala, this is just:
logger.debug("trace")
because the message parameter to debug in Scala has the type "=> String" which I think of as a parameter-less function that executes when it is evaluated, but which the documentation calls pass-by-name.
EDIT {
Functions in Scala are objects so there is an extra object here. For my work, the weight of a trivial object is worth removing the possibility of a log message getting needlessly evaluated.
}
This doesn't make the code faster but it does make it more likely to be faster and we're less likely to have the experience of going through and cleaning up other people's code en masse.
To me, this is a consistent theme within Scala.
Hard code fails to capture why Scala is faster though it does hint a bit.
I feel that it's a combination of code re-use and the ceiling of code quality in Scala.
In Java, awesome code is often forced to become an incomprehensible mess and so isn't really viable within production quality APIs as most programmers wouldn't be able to use it.
I have high hopes that Scala could allow the einsteins among us to implement far more competent APIs, potentially expressed through DSLs. The core APIs in Scala are already far along this path.
#higherkinded´s presentation on the subject - Scala Performance Considerations which does some Java/Scala comparisions.
Tools:
ScalaMeter
scala-benchmarking-template
Great blogpost:
Nanotrusting the Nanotime
Java and Scala both compile down to JVM bytecode, so the difference isn't that big. The best comparison you can get is probably on the computer language benchmarks game, which essentially says that Java and Scala both have the same memory usage. Scala is only slightly slower than Java on some of the benchmarks listed, but that could simply be because the implementation of the programs are different.
Really though, they're both so close it's not worth worrying about. The productivity increase you get by using a more expressive language like Scala is worth so much more than minimal (if any) performance hit.
The Java example is really not an idiom for typical application programs.
Such optimized code might be found in a system library method. But then it would use an array of the right type, i.e. File[] and would not throw an IndexOutOfBoundsException. (Different filter conditions for counting and adding).
My version would be (always (!) with curly braces because I don't like to spend an hour searching a bug which was introduced by saving the 2 seconds to hit a single key in Eclipse):
List<File> bigEnough = new ArrayList<File>();
for(String s : array) {
if(s.length() > 2) {
File file = mapping.get(s);
if (file != null) {
bigEnough.add(file);
}
}
}
But I could bring you a lot of other ugly Java code examples from my current project. I tried to avoid the common copy&modify style of coding by factoring out common structures and behaviour.
In my abstract DAO base class I have an abstract inner class for the common caching mechanism. For every concrete model object type there is a subclass of the abstract DAO base class, in which the inner class is subclassed to provide an implementation for the method which creates the business object when it is loaded from the database. (We can not use an ORM tool because we access another system via a proprietary API.)
This subclassing and instantiation code is not at all clear in Java and would be very readable in Scala.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Much of my programming background is in Java, and I'm still doing most of my programming in Java. However, I'm starting to learn Python for some side projects at work, and I'd like to learn it as independent of my Java background as possible - i.e. I don't want to just program Java in Python. What are some things I should look out for?
A quick example - when looking through the Python tutorial, I came across the fact that defaulted mutable parameters of a function (such as a list) are persisted (remembered from call to call). This was counter-intuitive to me as a Java programmer and hard to get my head around. (See here and here if you don't understand the example.)
Someone also provided me with this list, which I found helpful, but short. Anyone have any other examples of how a Java programmer might tend to misuse Python...? Or things a Java programmer would falsely assume or have trouble understanding?
Edit: Ok, a brief overview of the reasons addressed by the article I linked to to prevent duplicates in the answers (as suggested by Bill the Lizard). (Please let me know if I make a mistake in phrasing, I've only just started with Python so I may not understand all the concepts fully. And a disclaimer - these are going to be very brief, so if you don't understand what it's getting at check out the link.)
A static method in Java does not translate to a Python classmethod
A switch statement in Java translates to a hash table in Python
Don't use XML
Getters and setters are evil (hey, I'm just quoting :) )
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python
(And if you find this question at all interesting, check out the link anyway. :) It's quite good.)
Don't put everything into classes. Python's built-in list and dictionaries will take you far.
Don't worry about keeping one class per module. Divide modules by purpose, not by class.
Use inheritance for behavior, not interfaces. Don't create an "Animal" class for "Dog" and "Cat" to inherit from, just so you can have a generic "make_sound" method.
Just do this:
class Dog(object):
def make_sound(self):
return "woof!"
class Cat(object):
def make_sound(self):
return "meow!"
class LolCat(object):
def make_sound(self):
return "i can has cheezburger?"
The referenced article has some good advice that can easily be misquoted and misunderstood. And some bad advice.
Leave Java behind. Start fresh. "do not trust your [Java-based] instincts". Saying things are "counter-intuitive" is a bad habit in any programming discipline. When learning a new language, start fresh, and drop your habits. Your intuition must be wrong.
Languages are different. Otherwise, they'd be the same language with different syntax, and there'd be simple translators. Because there are not simple translators, there's no simple mapping. That means that intuition is unhelpful and dangerous.
"A static method in Java does not translate to a Python classmethod." This kind of thing is really limited and unhelpful. Python has a staticmethod decorator. It also has a classmethod decorator, for which Java has no equivalent.
This point, BTW, also included the much more helpful advice on not needlessly wrapping everything in a class. "The idiomatic translation of a Java static method is usually a module-level function".
The Java switch statement in Java can be implemented several ways. First, and foremost, it's usually an if elif elif elif construct. The article is unhelpful in this respect. If you're absolutely sure this is too slow (and can prove it) you can use a Python dictionary as a slightly faster mapping from value to block of code. Blindly translating switch to dictionary (without thinking) is really bad advice.
Don't use XML. Doesn't make sense when taken out of context. In context it means don't rely on XML to add flexibility. Java relies on describing stuff in XML; WSDL files, for example, repeat information that's obvious from inspecting the code. Python relies on introspection instead of restating everything in XML.
But Python has excellent XML processing libraries. Several.
Getters and setters are not required in Python they way they're required in Java. First, you have better introspection in Python, so you don't need getters and setters to help make dynamic bean objects. (For that, you use collections.namedtuple).
However, you have the property decorator which will bundle getters (and setters) into an attribute-like construct. The point is that Python prefers naked attributes; when necessary, we can bundle getters and setters to appear as if there's a simple attribute.
Also, Python has descriptor classes if properties aren't sophisticated enough.
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python. Correct. Python uses optional arguments instead of method overloading.
The bullet point went on to talk about closure; that isn't as helpful as the simple advice to use default argument values wisely.
One thing you might be used to in Java that you won't find in Python is strict privacy. This is not so much something to look out for as it is something not to look for (I am embarrassed by how long I searched for a Python equivalent to 'private' when I started out!). Instead, Python has much more transparency and easier introspection than Java. This falls under what is sometimes described as the "we're all consenting adults here" philosophy. There are a few conventions and language mechanisms to help prevent accidental use of "unpublic" methods and so forth, but the whole mindset of information hiding is virtually absent in Python.
The biggest one I can think of is not understanding or not fully utilizing duck typing. In Java you're required to specify very explicit and detailed type information upfront. In Python typing is both dynamic and largely implicit. The philosophy is that you should be thinking about your program at a higher level than nominal types. For example, in Python, you don't use inheritance to model substitutability. Substitutability comes by default as a result of duck typing. Inheritance is only a programmer convenience for reusing implementation.
Similarly, the Pythonic idiom is "beg forgiveness, don't ask permission". Explicit typing is considered evil. Don't check whether a parameter is a certain type upfront. Just try to do whatever you need to do with the parameter. If it doesn't conform to the proper interface, it will throw a very clear exception and you will be able to find the problem very quickly. If someone passes a parameter of a type that was nominally unexpected but has the same interface as what you expected, then you've gained flexibility for free.
The most important thing, from a Java POV, is that it's perfectly ok to not make classes for everything. There are many situations where a procedural approach is simpler and shorter.
The next most important thing is that you will have to get over the notion that the type of an object controls what it may do; rather, the code controls what objects must be able to support at runtime (this is by virtue of duck-typing).
Oh, and use native lists and dicts (not customized descendants) as far as possible.
The way exceptions are treated in Python is different from
how they are treated in Java. While in Java the advice
is to use exceptions only for exceptional conditions this is not
so with Python.
In Python things like Iterator makes use of exception mechanism to signal that there are no more items.But such a design is not considered as good practice in Java.
As Alex Martelli puts in his book Python in a Nutshell
the exception mechanism with other languages (and applicable to Java)
is LBYL (Look Before You Leap) :
is to check in advance, before attempting an operation, for all circumstances that might make the operation invalid.
Where as with Python the approach is EAFP (it's easier to Ask for forgiveness than permission)
A corrollary to "Don't use classes for everything": callbacks.
The Java way for doing callbacks relies on passing objects that implement the callback interface (for example ActionListener with its actionPerformed() method). Nothing of this sort is necessary in Python, you can directly pass methods or even locally defined functions:
def handler():
print("click!")
button.onclick(handler)
Or even lambdas:
button.onclick(lambda: print("click!\n"))