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 4 years ago.
Improve this question
One of the things that can be a little annoying about Java is the amount of code you need to express concepts. I am a believer in the "less code is better" philosophy, and I'd like to know how I can write Java without being so frustratingly verbose. Recently, I read the Hidden Features of Java question and was introduced to using double-brace initialization to simulate a List or Map literal. There are, of course, drawbacks to using this method, but it does allow you to do certain things with significantly fewer characters and (if you format it right) make the code a lot cleaner and clearer. I'm wondering if there aren't other clever tricks and lesser known language features which could make my code more concise.
I'd like to see answers with an explanation of the technique, the more verbose way which it replaces, and any potential drawbacks to using the technique.
Prior to the introduction of the diamond operator in Java 7, static factory methods for creating generic types could be used to reduce verbosity by reducing the need to repeat the type parameter. (This is because without the diamond operator, Java never infers the type parameter on constructors, but it will on methods calls.) Google Collections uses this technique, so you can write:
Set<MyClassWithALongName> set = Sets.newHashSet();
instead of:
Set<MyClassWithALongName> set = new HashSet<MyClassWithALongName>();
Look in the Lists, Sets and Maps classes of Google Collections for methods starting with "new" for more examples of this.
Unless you are writing for an old version of Java, as of Java 7 it is better to just use the diamond operator.
A similar one you probably already know about, using the "varargs" feature:
String[] array = new String[] {"stack", "over", "flow"};
List<String> list = Arrays.asList(array);
can be abbreviated
List<String> list = Arrays.asList("stack", "over", "flow");
Admittedly not a huge savings, but it does reduce the verbosity a little bit. As Thomas notes, the list will be immutable, so watch out for that. Actually, you can modify the list, you just can't change its length. Thanks to pimlottc for pointing that out.
Use a dependency injection framework like spring. I'm almost always amazed at how much code construction logic produces.
I've found that the most (only?) effective way to write concise java is to not write java at all. In cases where I needed to write something quickly that still interoperates with Java, I've found Groovy to be an excellent choice. Using a more concise language that still compiles to JVM bytecode can be an excellent solution. While I have no personal experiences with it, I've heard that Scala is an even better choice than Groovy in many cases.
Check out lambdaj. It has lots of features that can help to make your code more concise and readable.
Fluent interfaces can help - using builders and method chaining to make something resembling a DSL in java. The code you end up with can be a little harder to read though as it breaks Java's normal coding conventions such as removing the set / get from properties.
So in a fake Swing fluent interface you might define a button thus:
JButton button = Factory.button().icon(anIcon).tooltip("Wow").swing();
Another approach is to use another language there are many that integrate well with the JVM such as:
JRuby
Scala
Cal
A "closeQuietly" method can be used in try/finally blocks in situations where IO exceptions on close are uninteresting (or impossible).
Closeable c = null;
try {
...
c = openIt(...);
...
} finally {
closeQuietly(c);
}
where:
/** Close 'c' if it is not null, squashing IOExceptions */
public void closeQuietly(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException ex) {
// log error
}
}
}
Note that with Java 7 and later, the new "try with resources" syntax makes this particular example redundant.
I found a blog post giving an interesting technique which allows for writing a map literal in Java like you would be able to do in Perl, Python, Ruby, etc: Building your own literals in Java - Tuples and Maps
I really like this approach! I'll just summarize it here.
The basic idea is to create a generic pair class and define static functions that will construct a pair, and a map from a varargs array of pairs. This allows the following concise map literal definition:
Map(o("height", 3), o("width", 15), o("weight", 27));
Where o is the name of the static function to construct a pair of T1 and T2 objects, for any object types T1 and T2, and Map is the name of the static function to construct a Map. I'm not sure I like the choice of Map as the name of the map construction function because it is the same as the name of the Java interface, but the concept is still good.
Static initialisers
Example 1 (Map):
Map<String, String> myMap = new HashMap<String, String>() {{
put ("a", "b");
put ("c", "d");
}};
Example 2(List):
List<String> myList = new ArrayList<String>() {{
add("a");
add("b");
add("c");
}};
More Guave goodness to initialize immutable maps (which I'm finding to be a way more common case than initializing mutable maps): the ImmutableMap.of(...) variants
Map<Service, Long> timeouts = ImmutableMap.of(
orderService, 1500,
itemService, 500);
Ever have to iterate through a collection, just to map its elements by one of its properties? No more, thanks to Maps.uniqueIndex():
private void process(List<Module> modules) {
Map<String, Module> byName = Maps.uniqueIndex(modules, new Function<Module, String>() {
#Override public String apply(Module input) {
return input.getName();
}
});
or if this is frequent enough, make the function a public static final member of Module so that the above is reduced to:
Map<String, Module> byName = Maps.uniqueIndex(modules, Module.KEY_FUNCTION);
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I recently gave my source code to my friend so he could look over it and tell me if I have any major errors like memory-leaks, non thread-safe methods used in other Threads etc...
And he saw my HashmapWrapper class and told me that it was in-efficient, useless and a waste of space. I would really like to know why that is and if what he says is true.
The HashmapWrapper class:
public class HashmapWrapper<K, V>
{
public HashMap<K, V> wrapped;
public HashMapWrapper()
{
this.wrapped = new HashMap<K, V>();
}
public HashmapWrapper<K, V> put(K key, V value)
{
this.wrapped.put(key, value);
return this.wrapped;
}
public HashMap<K, V> get()
{
return this.wrapped;
}
}
It's a very simple class and it's only used to condense any code where I make hashmaps and then put values to them.
Here are some examples where I use the HashmapWrapper:
settings.save(new HashmapWrapper<String, String>().put("volume", this.volume.getString()).put("res", this.screen.resolution.getString()).put("music", this.soundSystem.isMusicAllowed().getString()).put("font", this.font.getFontName()).get());
set(new HashmapWrapper<String, Integer>().put("coord.x", this.entity.xCoord).put("", this.entity.yCoord).get());
I wouldn't say it's useless -- it does provide a convenient syntax for initializing a map -- but if you're just looking to save some typing on initialization, another way to achieve what you want is to use double brace initialization, which would look like this:
settings.save(new HashMap<String, String>() {{
put("volume", this.volume.getString());
put("res", this.screen.resolution.getString());
put("music", this.soundSystem.isMusicAllowed().getString());
put("font", this.font.getFontName()).get());
}});
An advantage of doing it this way is that you're still dealing with a subclass of Map and not a custom class.
I understand your thinking; you want to make method chaining possible. But let me just ask you something. What is easier to read?
Map<String, String> myHashMap = new HashMap<String, String>();
myHashMap.put("This", "Is");
myHashMap.put("Some", "text");
Instantly, we know what this does. You're adding two new entries to your HashMap.
myHashMap.put("This", "is").put("Some", "text");
It looks like I'm doing something with the value I just put in, doesn't it? Java has a convention and a standardized syntax, and a lot of the time that doesn't include method chaining with native Java objects. It's best to stick with the convention because the next guy is going to say..
What in the dancing f#!k is this?, when they're trying to wonder why your HashMap implements method chaining. Convention is not only to make your code more fluid; it's there to give the next guy an easier time of understanding the code that they're looking at.
Edit
Often, when you've got one very long line of code, it is common practise to carve it up into several lines to make it easier to read. A great example is when you're executing SQL:
db.executeQuery("SELECT * FROM TABLE WHERE ID IN (SELECT ID FROM OTHERTABLE WHERE ID = ?");
A little long, so let's format it a little.
db.executeQuery("SELECT *
FROM TABLE
WHERE ID IN (
SELECT ID
FROM OTHERTABLE
WHERE ID = ?");
Instantly, it's obvious you've got a nested SQL query.. Okay, let's follow the same idea with your code.
myMap.put("Hello", "there").put("my", "friend").put("this", "is").put("a", "really").put("long", "hashmap").put("entry", "and").put("gee", "this").put("line", "is").put("long", "!");
So, what do you do? Oh yeah, carve it up into different lines.
myMap.put("Hello", "there")
.put("my", "friend")
.put("this", "is")
.put("a", "really")
.put("long", "hashmap")
.put("entry", "and")
.put("gee", "this")
.put("line", "is")
.put("long", "!");
Ahh, readable. Alas, you've saved absolutely no space and you're back to square one! Method chaining is nice for a lot of different applications, but when it becomes longer and longer it fades into obscurity.
The reason your friend says the class is useless is because your wrapper doesn't add any substantial new functionality to a hashmap. The only thing your put method adds is the ability to chain put(k,v) commands which does not follow normal java style. Chaining commands tends to make code less readable and harder to debug/maintain.
If you want to be able to put multiple key value pairs into your hashmap in one line, a better way would be creating a method. Something similar to this.
public void put(Hashmap<k,v> map, k[] keys, v[] values){
if (k.size() != v.size()){
//throw error
} else {
for(int i = 0; i < k.size(); i++){
map.put(k[i], v[i]);
}
Obviously you could adjust how the method takes arguments. A two dimensional array would be another option, or just use the hashmap put method if you don't have to do this very often. Ultimately it's up to you.
I have the following model:
1 RepositoryDTO can have many ResourceDTOs, and in each ResourceDTO is exacly one TeamDTO.
So to get the TeamDTOs from the RepositoryDTO, I am doing the following:
RepositoryDTO repoDTO = ...
List<TeamDTO> teamsLinkedToRepo = getTeamsLinkedTo(repoDTO);
private List<TeamDTO> getTeamsLinkedTo(final RepositoryDTO repository) {
final List<TeamDTO> teamsLinkedToRepository = new ArrayList<TeamDTO>();
for (final ResourceDTO resourceDTO : repository.getResources()) {
teamsLinkedToRepository.add(resourceDTO.getTeam());
}
return teamsLinkedToRepository;
}
I'm just wondering is there a better idiom for doing this, maybe using Google Guava?
Keep simple things simple.
We used Google Guava excessively in one of our projects. And while it was less code and faster to read, it became a nightmare when debugging. So I advice to not use it until you get an huge advantage from it (and simple for-loops won't get any better with it).
With pure Java it's good code. There is no need to improve it.
Good code as Chris states, only one minor change if and only if possible and if the number of teams is potentially large you may wish to consider initialising the new ArrayList using new ArrayList(Integer), to avoid the underlying array being rebuilt. Potentially:
new ArrayList<TeamDTO>(repository.getResources().size());
For example, say I wanted to "extract" String[] fruits = {"Pear", "Banana", "Apple"}; into three separate variables, eg:
for (int i=0; i != fruits.length; ++i) {
// of course there's no eval in Java
eval("String fruit + i = " + fruits[i] + ";");
}
// ie: code that creates something equivalent to the following declarations:
String fruit0 = "Pear";
String fruit1 = "Banana";
String fruit2 = "Apple";
How could I do that, ignoring the "Why the heck would you want to do that?" question that you might be urged to ask me.
Similar questions have been asked many times before, but the real answer was never given, because what the OP really needed was to use a different approach. That's fine, but is this possible at all?
I have looked at reflection and it doesn't seem like there are any methods that would allow me even to add extra fields to an instance, let alone dynamically create locals.
Is it possible to create variables at runtime in Java?
The simple answer is No.
Java is a static language and does not support the injection of new variable declarations into an existing compiled program. There are alternatives (in order of decreasing usefulness / increasing difficulty):
Represent your "variables" as name / value pairs in a Map. Or come up with some other design that doesn't require real dynamic variables.
Use a scripting language that runs on the JVM and is callable from Java.
Use some kind of templating mechanism to generate new source code containing the declarations, and compile and load it dynamically.
Use a byte code manipulation library (e.g. BCEL) to create class files on the fly and then dynamically load them.
The first approach is the best. Java is a static language, and works best if you don't fight it. If this is a problem for you, maybe you are using the wrong language.
The last two are difficult / complicated and have significant performance costs. They are almost certainly not going to help ...
The question is not why you want to do it but 'what are you going to do with it?'. So suppose at runtime variable with the name fruits2 magically appeared on the stack of your method. Now what? You had to know its name at compile time to take advantage of it. Reflection will not help you access local variables.
Anyway, I would be interested if you described more detailed use case.
The way you phrased your question, people won't understand what you're asking. I believe (if I DO understand) the answer to your question (which should be phrased: "is it possible to dynamically create variables at run time") is "not as you've presented it".
You're right, there's no analog to javascript's (very powerful, but slow and fraught with hazards "eval" function) in Java, and that is precisely what you would need to get this to do what you're hoping to do.
The closest that exists is a hashmap (which is actually pretty close) where you can designate the key at run time, and then set the value. It's fairly versatile as you can have an map that will allow for whatever type you want stored in the field.
You're not going to be able to modify a class that's already been loaded into the JVM. However, you could conceivably use ASM < http://asm.ow2.org/ > or BCEL < http://commons.apache.org/bcel/> to dynamically generate a new class that has the dynamically-defined fields.
Way more trouble than it's worth. Seriously, just use a HashMap!
Would Janino be useful for you?
Here's some code. I think it's close to what you want, but I'm not sure.
package misc;
import java.lang.reflect.InvocationTargetException;
import org.codehaus.janino.CompileException;
import org.codehaus.janino.ScriptEvaluator;
import org.codehaus.janino.Parser.ParseException;
import org.codehaus.janino.Scanner.ScanException;
public class JaninoExample {
public static void main(String[] args) {
String in = " {\"Pear\", \"Banana\", \"Apple\"};";
try {
ScriptEvaluator se = new ScriptEvaluator("return new String[]"+in,String[].class);
try {
String[] fruits = (String[])se.evaluate(new Object[]{});
for(String fruit:fruits){
System.out.println(fruit);
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (CompileException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (ScanException e) {
e.printStackTrace();
}
}
}
Yes, for example, see Lombok library and specifically #log4j annotation that injects the log variable to the class
Can you perhaps elaborate, not sure what you're doing different here. Of course you can create three different strings. However i believe the syntax in java is string xx = new string("DDFD");
Edit:
By this i mean, what are you trying to change here. You can allocate memory dynamically therefore you can create "variables" dynamically. HOWEVER you cannot create a "variable" in the primitive fashion such as "int x = 0;" in run time, however you can add nodes to linked lists, resize arrays, etc during run time.
how can you emulate functional programming in java, specifically, doing things like map a function to a collection of items?
map(func, new String[]{"a","b","c"});
what's the least verbose & awkward way to do it?
All attempts of functional programming will have some part of verbose and/or awkward to it in Java, until Java 8.
The most direct way is to provide a Function interface (such as this one form Guava) and provide all kinds of methods that take and call it (such as Collections#transfrom() which does what I think your map() method should do).
The bad thing about is that you need to implement Function and often do so with an anonymous inner class, which has a terribly verbose syntax:
Collection<OutputType> result = Collections.transform(input, new Function<InputType,OutputType>() {
public OutputType apply(InputType input) {
return frobnicate(input);
}
});
Lambda expressions (introduced in Java 8) make this considerably easier (and possibly faster). The equivalent code using lambdas looks like this:
Collection<OutputType> result = Collections.transform(input, SomeClass::frobnicate);
or the more verbose, but more flexible:
Collection<OutputType> result = Collections.transform(input, in -> frobnicate(in));
I have used lambdaj and functionaljava for this sort of things. And there are probably others...
Just wrap the function you want to apply on the list with a class or an interface.
public interface Func {
Object f(Object input);
}
public void map (Func func, Object[] arr) {
for(int i=0;i<arr.legnth;i++) {
arr[i] = func.f(arr[i]);
}
}
map(
new Func() { public Object f(Object input) { return input; } };,
new String[]{"a","b"});
As you note, Java isn't designed for functional programming and while you can emulate it, you have to really want to do this even if is it more verbose and more awkward than using standard programming in Java.
Take #Joachim's example.
Collection<OutputType> result = Collections.transform(input, new Function<InputType,OutputType>() {
public OutputType apply(InputType input) {
return frobnicate(input);
}
});
This uses 12 symbols, not counting close brackets. The same thing in plain Java would look like.
List<OutputType> list = new ArrayList();
for(InputType in: input)
list.add(frobnicate(in));
This uses 7 symbols.
You can do functional programming in Java, but you should expect it to be more verbose and awkward than using the natural programming style of Java.
You could download OpenJDK 8 which is scheduled for prodcution release next year and use the new Lambda Expressions for functional programming. See http://macgyverdev.blogspot.se/2012/10/functional-programming-in-java.html for examples of how these closures will be used in the Collection APIs and how they compare with pre-Java 8 solutions like Guava and LambdaJ.
Coming from a Java background, I'm used to the common practice of dealing with collections: obviously there would be exceptions but usually code would look like:
public class MyClass {
private Set<String> mySet;
public void init() {
Set<String> s = new LinkedHashSet<String>();
s.add("Hello");
s.add("World");
mySet = Collections.unmodifiableSet(s);
}
}
I have to confess that I'm a bit befuddled by the plethora of options in Scala. There is:
scala.List (and Seq)
scala.collections.Set (and Map)
scala.collection.immutable.Set (and Map, Stack but not List)
scala.collection.mutable.Set (and Map, Buffer but not List)
scala.collection.jcl
So questions!
Why are List and Seq defined in package scala and not scala.collection (even though implementations of Seq are in the collection sub-packages)?
What is the standard mechanism for initializing a collection and then freezing it (which in Java is achieved by wrapping in an unmodifiable)?
Why are some collection types (e.g. MultiMap) only defined as mutable? (There is no immutable MultiMap)?
I've read Daniel Spiewak's excellent series on scala collections and am still puzzled by how one would actually use them in practice. The following seems slightly unwieldy due to the enforced full package declarations:
class MyScala {
var mySet: scala.collection.Set[String] = null
def init(): Unit = {
val s = scala.collection.mutable.Set.empty[String]
s + "Hello"
s + "World"
mySet = scala.collection.immutable.Set(s : _ *)
}
}
Although arguably this is more correct than the Java version as the immutable collection cannot change (as in the Java case, where the underlying collection could be altered underneath the unmodifiable wrapper)
Why are List and Seq defined in package scala and not scala.collection (even though implementations of Seq are in the collection sub-packages)?
Because they are deemed so generally useful that they are automatically imported into all programs via synonyms in scala.Predef.
What is the standard mechanism for initializing a collection and then freezing it (which in Java is achieved by wrapping in an unmodifiable)?
Java doesn't have a mechanism for freezing a collection. It only has an idiom for wrapping the (still modifiable) collection in a wrapper that throws an exception. The proper idiom in Scala is to copy a mutable collection into an immutable one - probably using :_*
Why are some collection types (e.g. MultiMap) only defined as mutable? (There is no immutable MultiMap)?
The team/community just hasn't gotten there yet. The 2.7 branch saw a bunch of additions and 2.8 is expected to have a bunch more.
The following seems slightly unwieldy due to the enforced full package declarations:
Scala allows import aliases so it's always less verbose than Java in this regard (see for example java.util.Date and java.sql.Date - using both forces one to be fully qualified)
import scala.collection.{Set => ISet}
import scala.collection.mutable.{Set => MSet}
class MyScala {
var mySet: ISet[String] = null
def init(): Unit = {
val s = MSet.empty[String]
s + "Hello"
s + "World"
mySet = Set(s : _ *)
}
}
Of course, you'd really just write init as def init() { mySet = Set("Hello", "World")} and save all the trouble or better yet just put it in the constructor var mySet : ISet[String] = Set("Hello", "World")
Mutable collections are useful occasionally (though I agree that you should always look at the immutable ones first). If using them, I tend to write
import scala.collection.mutable
at the top of the file, and (for example):
val cache = new mutable.HashMap[String, Int]
in my code. It means you only have to write “mutable.HashMap”, not scala.collection.mutable.HashMap”. As the commentator above mentioned, you could remap the name in the import (e.g., “import scala.collection.mutable.{HashMap => MMap}”), but:
I prefer not to mangle the names, so that it’s clearer what classes I’m using, and
I use ‘mutable’ rarely enough that having “mutable.ClassName” in my source is not an
undue burden.
(Also, can I echo the ‘avoid nulls’ comment too. It makes code so much more robust and comprehensible. I find that I don’t even have to use Option as much as you’d expect either.)
A couple of random thoughts:
I never use null, I use Option, which would then toss a decent error. This practice has gotten rid of a ton NullPointerException opportunities, and forces people to write decent errors.
Try to avoid looking into the "mutable" stuff unless you really need it.
So, my basic take on your scala example, where you have to initialize the set later, is
class MyScala {
private var lateBoundSet:Option[ Set[ String ] ] = None
def mySet = lateBoundSet.getOrElse( error("You didn't call init!") )
def init {
lateBoundSet = Some( Set( "Hello", "World" ) )
}
}
I've been on a tear recently around the office. "null is evil!"
Note that there might be some inconsistencies in the Scala collections API in the current version; for Scala 2.8 (to be released later in 2009), the collections API is being overhauled to make it more consistent and more flexible.
See this article on the Scala website: http://www.scala-lang.org/node/2060
To add to Tristan Juricek's example with a lateBoundSet: Scala has a built-in mechanism for lazy initialization, using the "lazy" keyword:
class MyClass {
lazy val mySet = Set("Hello", "World")
}
By doing this, mySet will be initialized on first use, instead of immediately when creating a new MyClass instance.