Using Init() in Map()

Using init() in map()

Simplified repro:

String.init as Character -> String
// error: type of expression is ambiguous without more context

This is because String has two initializers that accept one Character:

init(_ c: Character)
init(stringInterpolationSegment expr: Character)

As far as I know, there is no way to disambiguate them when using the initializer as a value.

As for (1...100).map(String.init), String.init is referred as Int -> String. Although there are two initializers that accept one Int:

init(stringInterpolationSegment expr: Int)
init<T : _SignedIntegerType>(_ v: T)

Generic type is weaker than explicit type. So the compiler choose stringInterpolationSegment: one in this case. You can confirm that by command + click on .init.

How to directly initialize a HashMap (in a literal way)?


All Versions

In case you happen to need just a single entry: There is Collections.singletonMap("key", "value").

For Java Version 9 or higher:

Yes, this is possible now. In Java 9 a couple of factory methods have been added that simplify the creation of maps :

// this works for up to 10 elements:
Map<String, String> test1 = Map.of(
"a", "b",
"c", "d"
);

// this works for any number of elements:
import static java.util.Map.entry;
Map<String, String> test2 = Map.ofEntries(
entry("a", "b"),
entry("c", "d")
);

In the example above both test and test2 will be the same, just with different ways of expressing the Map. The Map.of method is defined for up to ten elements in the map, while the Map.ofEntries method will have no such limit.

Note that in this case the resulting map will be an immutable map. If you want the map to be mutable, you could copy it again, e.g. using mutableMap = new HashMap<>(Map.of("a", "b"));

(See also JEP 269 and the Javadoc)

For up to Java Version 8:

No, you will have to add all the elements manually. You can use an initializer in an anonymous subclass to make the syntax a little bit shorter:

Map<String, String> myMap = new HashMap<String, String>() {{
put("a", "b");
put("c", "d");
}};

However, the anonymous subclass might introduce unwanted behavior in some cases. This includes for example:

  • It generates an additional class which increases memory consumption, disk space consumption and startup-time
  • In case of a non-static method: It holds a reference to the object the creating method was called upon. That means the object of the outer class cannot be garbage collected while the created map object is still referenced, thus blocking additional memory

Using a function for initialization will also enable you to generate a map in an initializer, but avoids nasty side-effects:

Map<String, String> myMap = createMap();

private static Map<String, String> createMap() {
Map<String,String> myMap = new HashMap<String,String>();
myMap.put("a", "b");
myMap.put("c", "d");
return myMap;
}

Initialize Map String, Object instance from Map entries

Replace

Map.of(a,b,c); 

with

Map.ofEntries(a,b,c);

If you want to still use Map.of() then you shall paste keys and values explicitly.

Map.Entry() returns an immutable Map.Entry containing the given
key and value. These entries are suitable for populating Map instances
using the Map.ofEntries() method.

When to use Map.of() and when to use Map.ofEntries()

How can I initialise a static Map?

The instance initialiser is just syntactic sugar in this case, right? I don't see why you need an extra anonymous class just to initialize. And it won't work if the class being created is final.

You can create an immutable map using a static initialiser too:

public class Test {
private static final Map<Integer, String> myMap;
static {
Map<Integer, String> aMap = ....;
aMap.put(1, "one");
aMap.put(2, "two");
myMap = Collections.unmodifiableMap(aMap);
}
}

Init a value in java map when not initialized

Even in Java 8, it's still possible. Jut use computeIfAbsent():

map.computeIfAbsent(key, k -> new AtomicInteger(0)).incrementAndGet();

According to the javadocs of computeIfAbsent

Returns:
the current (existing or computed) value associated with the specified key, or null if the computed value is null

Swift dictionary map - init in closure

Does your value for the dictionary need to be an optional? In a dictionary, when you assign its key as nil, the entry is deleted.

var params = [String:String?]()
params["lat"] = "40"
params["lon"] = "100"
params["key"] = "hey"
print(params) //result: ["lat": Optional("40"), "lon": Optional("100"), "key": Optional("hey")]
params["key"] = nil
print(params) //result: ["lat": Optional("40"), "lon": Optional("100")]

I suggest using a non optional-value dictionary. I have successfully written the code below:

import UIKit

var params = [String:String]()
params["lat"] = "40"
params["lon"] = "100"
let nsurl = params.map() {NSURLQueryItem.init(name: $0, value: $1)}
print(nsurl)
//Result:
//[<NSURLQueryItem 0x7f8252d29730> {name = lat, value = 40}, <NSURLQueryItem 0x7f8252d29700> {name = lon, value = 100}]

I hope this helps

How does jquery map to the init function in this code

In this code snippet if you look closely to window.methodDraw, it is a function, and at the end it will return Editor object instance that was configured and prepared throughout window.methodDraw function body, so since this instance object already have init method you can directly chain the call to it, here is a little snippet to demonstrate it in a simple way:





let Editor = {};


Editor.init = () => {

console.log('Editor.init');

}


let InitializerObj = (() => {

return Editor;

})()


InitializerObj.init();

Java initialize map with keys from set


Map<K, V> map = new HashMap<>();

setOfStrings.forEach(e -> map.put(e, false));

Can I declare and initialize a map in java with a literal?

For Java 9 and beyond, you can make use of Map#of, as well as Map#ofEntries with Map#entry:

Map<String, String> example = Map.ofEntries(
Map.entry("1", "one"),
Map.entry("2", "two"),
Map.entry("3", "three"),
//...
);

For shorter literals (10 or less entries), you can use Map#of directly (albeit with a slightly confusing syntax of Key1, Value1, Key2, Value2, ...):

Map<String, String> example = Map.of("1", "one", "2", "two");

Prior to Java 9, this would typically only be needed for initializing constant Map objects, for which a static initializer block is also useful:

private static final Map<String, String> MY_CONSTANT;

static {
Map<String, String> setup = new HashMap<>();
setup.put("1", "one");
setup.put("2", "two");
setup.put("3", "three");
MY_CONSTANT = Collections.unmodifiableMap(setup);
}

This will allow you to create a constant Map while allowing you to modify the map before it is set.

As pointed out by @Pshemo, there are numerous reasons to avoid double-brace initialization, however the notable exception to the "rule" is typically in constants much like the above example (as numerous anonymous classes would not be made). However, it is still possible to work around the need for double-brace initialization even this case, so it is overall best to avoid if possible. The only case I can think of this not being possible is within the context of a constant within an enum class, where the double-brace init may truly be the only true way to make this work.



Related Topics



Leave a reply



Submit