I have below five Integer variables and during the program, they are assigned some values randomly. I want to get the largest variable name but not the variable value. And I want to know if at least two of them have the same value. Please provide an example. Thank you.
int politics_counter = 0;
int economics_counter = 0;
int foreign_counter = 0;
int sport_counter = 0;
int weather_counter = 0;
And now for an answer (kind of)
public class MyThingie {
TreeMap<Integer, String> data = new TreeMap<Integer, String>();
public void doIt() {
...
insertElement("politics_counter", politics_counter);
insertElement("economics_counter", economics_counter);
insertElement("foreign_counter", foreign_counter);
insertElement("sport_counter", sport_counter);
insertElement("weather_counter", weather_counter);
System.out.println("Highest variable is "+data.lastEntry().getValue());
}
public void insertElement(String name, Integer i) {
if (data.get(i) == null) {
System.out.println("Element "+name+" has the name value as "+data.get(i));
}
else {
data.put(name,i);
}
}
}
and now for a more interesting answer:
public class BiggestFinder {
public void showBiggester(Object o) throws Exception {
TreeMap<Integer, String> data = new TreeMap<Integer, String)();
for (Field f : o.getDeclaredFields()) {
Object v = f.getValue(o);
if (v instanceof Integer) {
if (data.get(v)!=null) {
System.out.println("Value for "+f.getName()+" is the same as "+data.get(v));
}
else {
data.put((Integer)f.getValue(o), f.getName());
}
}
}
System.out.println("Largest is "+data.lastEntry().getValue());
}
}
which will interrogate an object and show the largest field, given that the object has members that are all Integers and that are all accessible to this method. There's a way to fudge that and improve it to make it more "robust".
As #Max suggested you can use a map for storing your variables and then manipulate the map for finding either biggest variable name or value.
// Initialize your map
HashMap<String, Integer> vars = new HashMap<String,Integer>();
// Inserting a variable
vars.put("politics_counter", new Integer(0));
// Looking for biggest variable
String biggestVar = "";
for (String key : vars.keySet()) {
if (key.length() > biggestVar.length)
biggestVar = key;
}
Related
my output is currently ("john") returns 0.25 and ("mary") also returns 0.25
public class Problem
{
private int count;
private final HashMap<String, Integer> counts;
public Problem() {
this.counts = new HashMap<>();
}
public void addName(String name)
{
Integer nameCount = counts.get(name);
if (nameCount == null)
{
nameCount = 1;
counts.put(name, nameCount);
nameCount++;
}
nameCount++;
count++;
}
this function should calculate the proportion
public double nameProportion(String name)
{
return counts.get(name) / (double) count;
}
public static void main(String[] args)
{
Problem namesCount = new Problem();
namesCount.addName("James");
namesCount.addName("John");
namesCount.addName("Mary");
namesCount.addName("Mary");
System.out.println("Fraction of Johns: " + namesCount.nameProportion("John"));
System.out.println("Fraction of Marys: " + namesCount.nameProportion("Mary"));
}
}
right now the output is incorrect, for some reason its not seeing the two marys as the same
Primitive and primitive wrapper are not immutable when you do nameCount++, it doesn't change the value of key in hashmap. It create another Integer object and put the value of nameCount +1 into that object, so the value of all key in hashmap in your code is 1.
It's all in your function Problem#addName. You are actually incrementing your nameCount at the end of the function, but the incremented value is lost when the function reaches the end of the block (nameCount is a local variable, not a member variable).
The solution to this is to increment nameCount if it is not null and put that into the counts map, like so for example:
public void addName(String name) {
Integer nameCount = counts.get(name);
if (nameCount == null) {
counts.put(name, 1);
} else {
counts.put(name, ++nameCount);
}
count++;
}
If it is null, then simply a 1 is put into the map for the corresponding name.
Incrementing the count is fine, because that is a member variable and is saved within the created namesCount reference to the Problem object.
You never update the Map if the name already exists in it. It is important to note that Integer objects are immutable; you can use AtomicInteger instead if you do not want to keep discarding previous objects. Demo
public void addName(String name) {
Integer nameCount = counts.get(name);
if (nameCount == null) {
nameCount = 1;
counts.put(name, nameCount);
} else {
counts.put(name, nameCount + 1);
}
count++;
}
This can be simplified using Map#getOrDefault. Demo
public void addName(String name) {
counts.put(name, counts.getOrDefault(name, 0) + 1);
count++;
}
I'm taking a binary String like this:
010010010000110100001010
as a String, converting it to Integer Array like this:
int[] DD = new DD[binString.length()];
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
and I'm tying to save these Integer values in to HashMap(I have to store into a HashMap as per instructions given to me) like this:
Map<String, Integer> toMemory = new HashMap<String, Integer>();
for(int i=0;i<binString.length();i++) {
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
if((DD[i] & (DD[i]-1) ) == 0) {
toMemory.put(new String("ON"), new Integer(DD[i]));
} else {
toMemory.put(new String("ON"), new Integer(DD[i]));
}
}
for(String s: toMemory.keySet()) {
if(s.startsWith("ON")) {
System.out.println(toMemory.get(s));
}
}
The issue I'm facing here is that, only one entry is being stored in the HashMap, say {"ON",0}. And no other values are being stored. My expected output is this:
{"ON" , 1 , "OFF" , 0, "ON" , 1 .........}
Is there any better way to store the values to get my expected output? Any help will be much appreciated.
P.S: Please ignore the recurring code, and I'm relatively new to programming.
Your usage of a Map is flawed. Maps take a unique key and return a value.
You are trying to use duplicate keys. Instead, look at using a List with a wrapper class:
class ClassName {
public String status;
public int value;
public ClassName(String status, int value){
this.status = status;
this.value = value;
}
}
List<ClassName> list = new ArrayList();
To add to the list, create a new instance of your class and call List#add:
list.add(new ClassName("ON", 1));
as Infuzed Guy said, you are using the Map the wrong way. It's a unique "key to value mapping".
As long as you are using several times the same key and want to store all the dada, you need to use a List.
Here is what I could come up with the little you gave us: test it here
import java.util.LinkedList;
import java.util.List;
class Main {
public static void main(String[] args) {
class Tuple<X, Y> { //The wrapper object
public final X x;
public final Y y;
public Tuple(X x, Y y) { //Object constructor
this.x = x;
this.y = y;
}
public String toString() //Here for printing purpose
{
return "\"" + this.x + "\", " + this.y;
}
}
//Note here te use of List
List<Tuple> toMemory = new LinkedList<>();
String binString = "10100100101100101011";
int[] DD = new int[binString.length()];
for(int i=0; i < binString.length(); ++i)
{
//Here I use the char value
//to get the by subtraction
DD[i] = binString.charAt(i) - '0';
if(DD[i] == 1) //Simple check with the int value
{
toMemory.add(new Tuple<>("ON", DD[i]));
}
else
{
toMemory.add(new Tuple<>("OFF", DD[i]));
}
}
//Print the List
System.out.print("{ ");
for(Tuple s: toMemory) {
System.out.print(s +", ");
}
System.out.println("}");
}
}
Example:
d1 = "the sky is blue"
d2 = "the car is blue"
Key Value
the [<d1,1>,<d2,1>]
sky [<d1,1>]
is [<d1,1>,<d2,1>]
blue [<d1,1>,<d2,1>]
car [<d2,1>]
Where:
key = String
ex:
<d1,1>
d1 = Document id
1 = How many times the word apear on file
I created a document type object with the docid variables and frequency.
public class Documento {
private final int docid;
private final int frequencia;
public Documento(int docid, int frequencia) {
this.docid = docid;
this.frequencia = frequencia;
}
public int getDocid() {
return docid;
}
public int getFrequencia() {
return frequencia;
}
#Override
public boolean equals(Object o) {
if ((o instanceof Documento) && docid == ((Documento) o).docid && frequencia == ((Documento) o).frequencia) {
return true;
}
return false;
}
And the dictionary class that is a hashmap with
public class Dicionario {
public Map<String, Documento> indice = new HashMap<>();
public void InsereDicionario(String palavra, int docid) {
int cont = indice.containsKey(palavra) ? indice.get(palavra).getFrequencia() : 0;
indice.put(palavra, new Documento(docid, cont + 1));
}
public int frequencia(String palavra) {
return indice.get(palavra).getFrequencia();
}
public void criaDicionario(String entrada) {
String[] palavras = entrada.split("\\s+");
for (int i = 0; i < palavras.length; i++) {
InsereDicionario(palavras[i], 1);
}
}
public void ListaPalavras(){
for(String key:indice.keySet()){
System.out.println("");
}
}
But what I really need the dictionary is a list of documents , and I do not know how to do this , someone could help me ?
or is there an easier way to do this ?
If you need a list of documents, why not create one? With Java8 this becomes even more convenient:
For example:
public Map<String, List<Documento>> indice = new HashMap<>();
//register new word
indice.putIfAbsent(palavra, new ArrayList<>());
//add additional occurence
indice.get(palavra).add(documento);
//get frequency
int frequencia = indice.get(palavra)
.stream()
.map(d -> d.getFrequencia())
.reduce(0, (s, i) -> s + i);
An alternative would be to use Guava's Multimap, see here
Map<String, List<Documento>>
Obviously you need to adapt the rest of the code.
For example, when you need to add something to the dictionary, if it's the first time you need to create the List with that single document, next time you need to take the already created list and add documents there.
I'm creating an educational game for young students who needs to learn the most common words. On random I pick three words of the list, show them on the screen, play an audio recording of one of the three words and then the student has to pick the word that has been pronounced. I keep track of how many times they have guessed each word. In that way I can set up a criteria for when new words should be introduced to the student. When three of the words are picked I'll like to pronounce the word that the student has had least exposure to.
I have a HashMap called words, which contains the words, and a integer value of how many times the student guessed the word.
HashMap<String,Integer> words
It contains between 10 - 120 keys/words. I'll like to create a method, which takes three of the hash map keys as parameters, that can return the String/key having the lowest value of the keys asked for.
I have had trouple getting this to work as intended and I'd appreciate any help.
Possibly the shortest solution, with Java 8:
private String getMinKey(Map<String, Integer> map, String... keys) {
return map.entrySet().stream()
.filter(p -> Arrays.asList(keys).contains(p.getKey()))
.min(Comparator.comparingInt(Map.Entry::getValue)).get().getKey();
}
What about this?
private String getMinKey(Map<String, Integer> map, String... keys) {
String minKey = null;
int minValue = Integer.MAX_VALUE;
for(String key : keys) {
int value = map.get(key);
if(value < minValue) {
minValue = value;
minKey = key;
}
}
return minKey;
}
First get the entry set from the map:
Set<Entry<String,Integer>> entries = map.entrySet();
Now dump that into an ArrayList so you can sort it:
List<Entry<String,Integer>> sortedEntries = new ArrayList<>(entries);
Now sort the list:
Collections.sort(sortedEntries, /*Define your comparitor here to compare by values */);
Your list now has the contents of the map sorted by value, you can access them in whatever order you like.
This is a variation of the answer of user3309578
static HashMap words = new HashMap();
private static String getMax () {
String minKey = null;
int minValue = Integer.MAX_VALUE;
for (String key : words.keySet()) {
int value = words.get(key);
if (value < minValue) {
minValue = value;
minKey = key;
}
}
return minKey;
}
public static void main (String[] args) {
words.put("a", 2);
words.put("b", 4);
words.put("c", 6);
words.put("d", 8);
words.put("e", 1);
words.put("f", 3);
words.put("g", 5);
words.put("h", 7);
System.out.println(getMax());
}
i made this, it can hold multiple keys=
HashMap<String,Integer>hashmap_original=new HashMap<>();
hashmap_original.put("key_1",1);
hashmap_original.put("key_2",4);
hashmap_original.put("key_3",1);
hashmap_original.put("key_4",3);
HashMap<String,Integer>hashmap_result=new HashMap<>();
int int_minium_value = 9999; //put a maxium value that u know your code it wont pass it
for (String String_key:hashmap_original.keySet()) {
int int_compare_value=hashmap_original.get(String_key); //get the value
if (int_compare_value<int_minium_value) {
int_minium_value=int_compare_value;
hashmap_result.clear(); //delete non min values
hashmap_result.put(String_key,int_compare_value);
} else if (int_compare_value==int_minium_value) {
hashmap_result.put(String_key,int_compare_value);
}
}
String result=null;//u can use a ArrayList
for (String key_with_the_lowest_value : hashmap_result.keySet()) {
if (result == null) {
result = key_with_the_lowest_value;
} else {
result=result+","+key_with_the_lowest_value;
}
}
Java newbie, what I am trying to do is retrieve a string name that prints to the screen if one of the multiple values is within a range as follows:
public class SuperHeroes {
private Map<String, Set<Integer>> names;
private Set<Integer> pageNum;
/**
* Constructor for objects of class SuperHeroes
*/
public SuperHeroes() {
names = new HashMap<>();
pageNum = new TreeSet<>();
}
/**
* The fill() method creates 2 entries.
*/
public void fill() {
pageNum.add(1);
pageNum.add(3);
pageNum.add(7);
names.put("Kent,Clark", pageNum);
pageNum = new TreeSet<>();
pageNum.add(2);
pageNum.add(6);
pageNum.add(4);
names.put("Wayne,Bruce", pageNum);
}
public void findInRange(int num, int numb) {
for (String eachName: names.keySet()) {
for (int eachNum:pageNum) {
if(eachNum >= num && eachNum <= numb) {
System.out.println(names.get(eachName));
}
}
}
}
}
The result printed to screen would be the name of superhero if the pageNum is within the range. thr output I get at the moment is all the numbers. Any help would be gratefully received. If you can point me in the right direction would be a help.
Thank you in advance.
First mistake in your code is the way you defined names and pageNum. It should be in this way:
public SuperHeroes()
{
names = new HashMap<String, Set<Integer>>();
pageNum = new TreeSet<Integer>();
}
Now You could use subSet() method of Treeset to achieve what you looking for . Here the code goes:
EDIT: While retrieving the Treeset for given name from names the returned value is needed to be typecast to TreeSet type. Same is to be done while using the subset method with tSet .
public void findInRange(int num, int numb)
{
for (String eachName: names.keySet())
{
TreeSet<Integer> tSet = (TreeSet<Integer>)names.get(eachName);
TreeSet<Integer> subSet = new TreeSet<Integer>();
subSet = (TreeSet<Integer>)tSet.subSet(num,true,numb,true);//for JDK 1.6 or above. returns num<=numbers<=numb
//TreeSet<Integer> subSet = tSet.subSet(num-1, numb+1);//for JDK version less than 1.6
if (subSet.size() != 0)
{
System.out.println("Hero is "+eachName);
break;//you can ommit it if you want to print all heroes having pagenum in range num to numb
}
}
}
The fill method is also needed to be modified as:
public void fill()
{
pageNum.add(1);
pageNum.add(3);
pageNum.add(7);
names.put("Kent,Clark", pageNum);
pageNum = new TreeSet<Integer>();//Use proper way of object construction with generics
pageNum.add(5);
pageNum.add(6);
pageNum.add(4);
names.put("Wayne,Bruce", pageNum);
}
First, you must use the name of the super hero for obtaining the treeset, then read every item in the tree and compare it with the number you need, if the comparison is true print the name of the superhero.
Look at this link
http://www.easywayserver.com/blog/java-treeset-example/
Best regards
You're telling it to print the numbers corresponding to the found name with the line
System.out.println(names.get(eachName));
If you only want to show the name, that should just be
System.out.println(eachname);
Well we are all guessing here. Maybe you need this :
public void findInRange(int num, int numb)
{
for (String eachName : names.keySet())
{
for (int eachNum : pageNum)
{
if (eachNum >= num && eachNum <= numb)
{
for (int temp = 0; temp < eachNum; temp ++)
{
System.out.println(eachName);
}
}
}
}
}
Wondering, you have initialised an pageNum in the constructor, why you are creating another one in the method fill()? That maybe the reason because the one in constructor may "hiding" from the second one in the fill method.
If anybody is interested I solved this with the following code:
public void findInRange(int num, int numb)
{
for(String eachName: names.keySet())
{
pageNum = names.get(eachName);
for (int eachNum:pageNum)
{
if(eachNum>=num&&eachNum<=numb||eachNum>=numb&&eachNum<=num)
{
System.out.println(eachName);
break;
}
}
}
}