I have to store some machine details in redis. As there are many different machines i am planning to use the below structure
server1 => {name => s1, cpu=>80}
server2 => {name => s2, cpu=>40}
I need to store more than one value against the key CPU. Also i need to maintain only the last 10 values in the list of values against cpu
1) How can i store a list against the key inside the hash?
2) I read about ltrim. But it accepts a key. How can i do a ltrim for key cpu inside server1?
I am using jedis.
Redis' data structures cannot be nested inside other data structures, so storing a List inside a Hash is not possible. Instead, use different keys for your servers' CPU values (e.g. server1:cpu).
It's possible to do this with Redisson framework. It allows to store a reference to Redis object in another Redis object though special reference objects which handled by Redisson.
So your task could be solved using List inside Map:
RMap<String, RList<Option>> settings = redisson.getMap("settings");
RList<Option> options1 = redisson.getList("settings_server1_option");
options1.add(new Option("name", "s1"));
options1.add(new Option("cpu", "80"));
settings.put("server1", options1);
RList<Option> options2 = redisson.getList("settings_server2_option");
options2.add(new Option("name", "s2"));
options2.add(new Option("cpu", "40"));
settings.put("server2", options2);
// read it
RList<Option> options2Value = settings.get("server2");
Or using Map inside Map:
RMap<String, RMap<String, String>> settings = redisson.getMap("settings");
RMap<String, String> options1 = redisson.getMap("settings_server1_option");
options1.put("name", "s1");
options1.put("cpu", "80");
settings.put("server1", options1);
RMap<String, String> options2 = redisson.getMap("settings_server2_option");
options2.put("name", "s2");
options2.put("cpu", "40");
settings.put("server2", options1);
// read it
RMap<String, String> options2Value = settings.get("server2");
Diclamer: I'm a developer of Redisson
You can encode/stringify push the data, while pulling data you can decode/parse the data.
Encode -> Decode
Stringify -> Parse
Related
How do I write this in Java?
//js
const hello = {
foo: "bar",
test: "world",
name: "david"
}
I want have a very long object, then refer it back like hello[test] or hello[foo]
I've heard of hashmaps, but you can only create an empty one and then add elements into it.
I've got a really long list like that in js. How can I copy those into Java? Doing .put() one by one would take forever, and I don't think that's efficient.
And even if someone wrote a script to turn uwu: "owo" into hello.put("uwu", "owo");, it'd be ugly in the code with a big block of hello.put()s.
I also don't want to create a new file for that (it only has around 34 lines) and want to keep it in the code. Also, because I have three more like these with 20-40 keys and values in each of them, I don't want to create three extra files with just 30 lines in them. I also don't want to go into complexity of reading them.
Oh and also, I won't be changing the hashmap btw, just reading data like a constant.
In summary, can I do something like this in Java for long lists without doing .put()?
public HashMap<String, String> hello = new HashMap<String, String>(
"foo": "bar",
"test": "world",
"name": "david",
"uwu": "owo"
);
And refer to them like hello["name"]? I also don't want this thing.
public HashMap<String, String> hello = new HashMap<String, String>();
hello.put("foo", "bar");
hello.put("test", "world");
hello.put("name", "david");
hello.put("uwu", "owo");
//for 25 more lines
public HashMap<String, String> hello2 = new HashMap<String, String>();
hello2.put("stuff", "thing");
//... for around 20 more lines
//repeat for 3 more hashmaps
In modern Java (14 and later) you can use a record:
record Hello(String foo, String test, String world) { }
and create an instance like this:
final Hello hello = new Hello("bar", "world", "david");
You access the values like:
System.out.print(hello.foo());
Using a record has the advantage that your data is statically typed -- you can't mistype a key, or forget to remove usages of a key you've removed from the record.
IN Java 14 and beyond, I would recommand using a record, as explained in the other answer.
It's the safest and also probably the most efficient way.
For Java 9 to 14, you may use Map.of("hello", "world", "foo", "bar");.
But you may not be able to go beyond a certain number of key/value pairs.
For java 8 and below, or if you exceed the number of arguments allowed with Map.of, you don't have other choice than create an empty map and put key/value pairs one by one.
Note however that, performances aren't necessarily going to be worse.
You can of course reimplement your own version of Map.of with variable number of arguments.
Since you need something constant like, you can save those values in files and read from those files. For example save data in file in json format:
{
"foo": "bar",
"test": "world",
"name": "david"
}
Then parse this file to a Map.
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(ClassLoader.getSystemResourceAsStream("constants.json"), Map.class);
map.forEach((k, v) -> System.out.println(k + " -> " + v));
}
}
This example uses reading file as project resource and uses ObjectMapper to parse json to Map, but you can use any other tool for the same effect. If the data format is simple enough(string key to string value, no nested arrays, objects and such) you can save it in even simpler format and do the read, parse, add to map manually.
Hi is right pass HashMap to functions in repository
void sendComment(HashMap<String, String> data){
FirebaseDatabase.getInstance(). getRefrence().setValue(data);
}
And in viewmodel i create HashMap var and add key,value to it like
HashMap<String, String> data=new HashMap<>();
data.add("commentText","any text");
data.add("senderId","any text");
data.add("postId","any text");
repo.sendComment(data);
Is that true or should i add arguments senderId,postId,commentText
In function in repository
Like
void sendComment(String postId,String senderId){
//Add to database code
}
first of all you can use SparseArray instead of HashMap . because SparseArray is intended to be more memory-efficient than a HashMap, because it avoids auto-boxing keys and its data structure doesn't rely on an extra entry object for each mapping
depends on your task .
SparseArray<Int>().set(key , value)
you can use the repository for change any object(data) to save in DB or send to the server and change any object(data) to pass to ui and viewModel .
Im traslating a old enterprise App who uses C# with Linq queries to Java 8. I have some of those queries who I'm not able to reproduce using Lambdas as I dont know how C# works with those.
For example, in this Linq:
from register in registers
group register by register.muleID into groups
select new Petition
{
Data = new PetitionData
{
UUID = groups.Key
},
Registers = groups.ToList<AuditRegister>()
}).ToList<Petition>()
I undestand this as a GroupingBy on Java 8 Lambda, but what's the "select new PetitionData" inside of the query? I don't know how to code it in Java.
I have this at this moment:
Map<String, List<AuditRegister>> groupByMuleId =
registers.stream().collect(Collectors.groupingBy(AuditRegister::getMuleID));
Thank you and regards!
The select LINQ operation is similar to the map method of Stream in Java. They both transform each element of the sequence into something else.
collect(Collectors.groupingBy(AuditRegister::getMuleID)) returns a Map<String, List<AuditRegister>> as you know. But the groups variable in the C# version is an IEnumerable<IGrouping<string, AuditRegister>>. They are quite different data structures.
What you need is the entrySet method of Map. It turns the map into a Set<Map.Entry<String, List<AuditRegister>>>. Now, this data structure is more similar to IEnumerable<IGrouping<string, AuditRegister>>. This means that you can create a stream from the return value of entry, call map, and transform each element into a Petition.
groups.Key is simply x.getKey(), groups.ToList() is simply x.getValue(). It should be easy.
I suggest you to create a separate method to pass into the map method:
// you can probably came up with a more meaningful name
public static Petition mapEntryToPetition(Map.Entry<String, List<AuditRegister>> entry) {
Petition petition = new Petition();
PetitionData data = new PetitionData();
data.setUUID(entry.getKey());
petition.setData(data);
petition.setRegisters(entry.getValue());
return petition;
}
I am not sure how to define the key for the message size of my KafkaSpouts.
My example:
Map<String, Object> props = new HashMap<>();
props.put("fetch.message.max.bytes", "2097152"); // 2MB
props.put(KafkaSpoutConfig.Consumer.GROUP_ID, group);
I searched for the constant key definition of "fetch.message.max.bytes" without succeed.
I expect this key in KafkaSpoutConfig.Consumer or at least KafkaSpoutConfig.
Anyone know the correct location?
Storm's KafkaSpout does not offer all available keys as perdefined members. However, if you know the name of the key, you can safely use a String (as shown in your example) of use a Kafka class that defines the key.
I am reading a simple JSON....
{"A":0,"B":0,"C":2,"D":0,"F":5}
into a map using JsonSlurper in Groovy...
Map gradeDistributon = jsonSlurper.parseText(jsonString)
But when iterating over this map with a closure..
gradeDistributon.each{ entry ->
println "From map got key ${entry.key}"
I am seeing the keys are not in the order they were in the original JSON, for example 'C' comes first. I think this is because Map does not maintain insertion order in Java. Is there a way I can keep the order of the original JSON?
If it means reading the JSON in a different way (instead of into a Map with JsonSlurper) then I am fine with that if you can show me how.
You can set JVM system property jdk.map.althashing.threshold to make JsonSlurper to use a LinkedHashMap instead of TreeMap as the internal Map implementation, e.g. -Djdk.map.althashing.threshold=512.
The reason is in source code of groovy.json.internal.LazyMap used by JsonSlurper.
private static final String JDK_MAP_ALTHASHING_SYSPROP = System.getProperty("jdk.map.althashing.threshold");
private void buildIfNeeded() {
if (map == null) {
/** added to avoid hash collision attack. */
if (Sys.is1_7OrLater() && JDK_MAP_ALTHASHING_SYSPROP != null) {
map = new LinkedHashMap<String, Object>(size, 0.01f);
} else {
map = new TreeMap<String, Object>();
}
}
}
Please note this solution should be used as a hack as it depends on Groovy's internal implementation details. So this behavior may change in future version of Groovy.
See my blog post for details.
So it was just a matter of sorting the keys after JsonSlurper built the Map, for that I just read into a TreeMap which sorts the keys by default..
TreeMap gradeDistributon = jsonSlurper.parseText(jsonString)
I can't reproduce your behaviour with groovy 2.4.5 but you can try using LinkedHashMap (allow to iterate over map keys maintaining the order in which the entries were inserted):
import groovy.json.*
def jsonText = '''
{"A":0,"B":0,"C":2,"D":0,"F":5,"G":7,"H":9}
'''
LinkedHashMap json = new JsonSlurper().parseText(jsonText)
json.each{ entry ->
println "${entry.key}"
}
NOTE: as stated by #XenoN the JsonSlurper() sort the json keys during the parsing process so independently of the input order (ie. {"H":0,"B":0,"A":2,"D":0,"G":5,"F":7,"C":9}) the output of JsonSlurper will be always: {"A":2,"B":0,"C":9,"D":0,"F":7,"G":5,"H":0}.
Using the LinkedHashMap instead of a HashMap we preserve the order given by JsonSlurper.
I run the same code on Groovy 2.4.x and on 3.0.x.
On 2.4 the order is preserved,but on 3.0 is sorted asc by default.
use the JsonSluperClassic().parse() instead it will preserve the order