Appropriate Data structure of java to find unique word from file - java

I have a requirement to parse a file which contains 1000 of sentences in the file.
where I have to find a unique word in a file means that has not come more than one time in the file.
which data structure of should I use.(need to perform this operation using DS of java only)and why and how
2nd Question is
map.put("abc","hello");
map.put.("ABC","hi");
when we are inserting in map object as given above code what will happen.

Use Map, use the word as key and value as count, for every word you have put it in the map and increment the count by one.
if(map.containsKey("some")){
// get the current value
int currentValue = map.get("some");
// put back the key with incremented value
map.put("some",currentValue+1);
} else {
// first time
map.put("some",1);
}
For your second question, both put will be added in the Map since map key is case sensitive.

You can fill your words in a map witch has a key the word and the value the number of occurrence.
When you finish filling your data in your Map loop again again check the value if great then on or equal one, if it is great then one, remove it from your map.
And you can return the size of this map in the end, to know the number of unique words
If you dont want to use just abc or ABC, you ca use LowerCase or UpperCase when you insert in your Map.
Here a simple example you can go throw :
public static void main(String[] args) {
//i consider you know how to learn from a file, i use a simple array just to explain
String[] listWords = {"hello", "word", "hello", "stack", "HELLO", "WORD", "123", "what?"};
//fill your words in your map
Map<String, Integer> map = new HashMap<>();
for (String word : listWords) {
if (!map.containsKey(word.toLowerCase())) {
map.put(word.toLowerCase(), 1);
} else {
map.put(word.toLowerCase(), map.get(word.toLowerCase()) + 1);
}
}
//print your map
map.entrySet().forEach((entry) -> {
System.out.println("word : " + entry.getKey() + " occurence : " + entry.getValue());
});
System.out.println("**************************************************");
//loop throw your map and remove the words which occurrence > 1
for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Integer> entry = it.next();
if (entry.getValue() > 1) {
it.remove();
}
}
//print your map again
map.entrySet().forEach((entry) -> {
System.out.println("word : " + entry.getKey() + " occurence : " + entry.getValue());
});
//size of your end map
System.out.println("Size of map = " + map.size());
}
Some good references you can base one to play with maps:
How to update a value, given a key in a java hashmap?
iterating over and removing from a map
Hope this can gives you an idea.

Related

Finding duplicate using HashMap in java not working

I am new to java.I searched this problem in SO but I tried in my own way.I have map and it is printing following :
Key = MX Week Email Pulls 010521 -010621_22780_1, Value = 010521010621
Key = MX Week Email Pulls 010721 -010921_23122, Value = 010721010921
Key = MX Week Email Pulls 010321 -010421_22779, Value = 010321010421
Key = MX Week Email Pulls 010521 -010621_22780, Value = 010521010621
Since,key is different,I want to find duplicate of these keys by using values. Since the duplicate value above is:
010521010621
010521010621
I tried to find duplicate by increasing count value:
public void doAnalysis(Map<String,String> mapAll) {
List<String> listOf=new ArrayList<>();
Map<String,Integer> putDupli=new HashMap<String, Integer>();
for (Map.Entry<String,String> entry : mapAll.entrySet()) {
System.out.println("Key = " + entry.getKey() +
", Value = " + entry.getValue());
if(!putDupli.containsValue(entry.getValue())) {
putDupli.put(entry.getValue(),0);
}
else {
putDupli.put(entry.getValue(),putDupli.get(entry.getKey())+1);
}
}
System.out.println(putDupli);
}
The line System.out.println(putDupli); is printing
{010521010621=0, 010721010921=0, 010321010421=0}
My expected output was:
{010521010621=2, 010721010921=0, 010321010421=0}
Should be if(!putDupli.containsKey(entry.getValue())) {
instead of
if(!putDupli.containsValue(entry.getValue())) {
as the other map is putting the value as key.
Also, putDupli.put(entry.getValue(),putDupli.get(entry.getKey())+1);
should be
putDupli.put(entry.getValue(), putDupli.get(entry.getValue()) + 1);.
Furthermore, you probably want the initial count to be 1 instead of 0.
If catching those bugs is hard at first, try using a debugger.
If you are using java 8, you can use Stream to get the count
Map<String, Long> dupliMap = mapAll.values().stream()
.collect(Collectors.groupingBy(
x -> x,
Collectors.counting()
));
try this:
!putDupli.containsValue(entry.getValue().toString)
As your comapring the values of an Integer to String.
You might want to consider a different approach. Create a Map<Integer,List<Long>> to store the values as follows:
String[] data = { "010521,010521010621",
"010721,010721010921", "010321,010321010421",
"010521,010521010621" };
Map<Integer, List<Long>> map =
Arrays.stream(data).map(str -> str.split(","))
.collect(Collectors.groupingBy(
arr -> Integer.valueOf(arr[0]),
Collectors.mapping(
arr -> Long.valueOf(arr[1]),
Collectors.toList())));
Then you can find the count of each value.
for (List<Long> list : map.values()) {
System.out.println(list.get(0) + "=" + list.size());
}
Prints
10321010421=1
10721010921=1
10521010621=2

How to print a single Key-Value pair in a HashMap in java?

Is it possible to do so? If yes, what is the required syntax/method?
I tried it by using,
System.out.println(key+"="+HM.get(key));
but it prints it in this format,
key= value
whereas, I need
key=value
(Due to outputting format in HackerRank)
while(sc.hasNextLine())
{
String s=sc.nextLine();
if(a.containsKey(s))
{
System.out.println(s+"="+a.get(s));
}
else
System.out.println("Not found");
}
EDIT 1:
I saw the solution given, the person used the following code,
while(scan.hasNext()){
String s = scan.next();
Integer phoneNumber = phoneBook.get(s);
System.out.println(
(phoneNumber != null)
? s + "=" + phoneNumber
: "Not found"
);
}
Now, why does this not have white space in the answer?
The only visible change I see is that this person used an object instead of primitive data type.
Also,this person used int instead of string in accepting the phone number, I initially did the same but it gave me an InputMismatchException .
There is no avalilable method in https://docs.oracle.com/javase/7/docs/api/java/util/Map.html to get Entity from map if there is any key or value available. Try below code if it help :
if (map.containsKey(key)) {
Object value = map.get(key);
System.out.println("Key : " + key +" value :"+ value);
}
You can use entrySet() (see entrySet) to iterate over your map.
You will then have access to a Map Entry which contains the methods getValue() and getKey() to retreive both the value and the key of your mapped object.
entrySet() returns a Set, and Set extends Collection, which offers the stream() method, so you can use stream to loop over and process your entrySet :
map
.entrySet() // get a Set of Entries of your map
.stream() // get Set as Stream
.forEach( // loop over Set
entry -> // lambda as looping over set entries implicitly returns an Entry
System.out.println(
entry.getKey() // get the key
+ "="
+ entry.getValue() // get the value
);
If needed, you can add .filter() to process only elements that matches your conditions in your Stream.
Working example here
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, String> myMap = new HashMap<String, String>() {
private static final long serialVersionUID = 1L;
{
for (int i = 1 ; i < 10 ; i++) {
put("key"+i, "value"+i);
}
}
};
myMap.entrySet().stream().forEach(
entry -> System.out.println(entry.getKey() + "=" + entry.getValue())
);
}
}
Output :
key1=value1
key2=value2
key5=value5
key6=value6
key3=value3
key4=value4
key9=value9
key7=value7
key8=value8

How to retrieve one record at a time from Dictionary Class in java

I am inserting records in Dictionary and while retrieving i am using code something like this:
System.out.println(newLine + "Items in the dictionary..." + dict + newLine);
and it is giving me result as:
Items in the dictionary...{pa=1234567890, abcd=8976543245}
but i want it in different manner. i want to access each record and field separately.
I want result something like this:
Name Contact
pa 1234567890
abcd 8976543245
Dictionary has keys method to get keys you can iterate over than and get values
Enumeration<String> e = dictionary.keys();
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}
If it's a custom collection, you can write your own Iterator
If it's a Map or HashTable
You can iterate over dictionary using
Example
for (Entry<String, String> entry : dict.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
for (String key : dict.keySet()) {
System.out.println(key + " " + dict.get(key));
}
In Java8
dict.forEach((k, v) -> System.out.println(k + " " + v));
Dictionary has keys method to get keys you can iterate over than and get values
EDIT
change your declaration to
Hashtable<String, String> dict = new Hashtable<String, String>(); so that you'll get the methods to iterate over HashTable
You can use a for loop to iterate over dict.keys(), then retrieve the value for each key using dict.get().

HashMap, return key and value as a list

I have an homework to do, so I have finished the script but the problem is with the values.
The main code is (I cannot change it due to homework) :
List<String> result = cw.getResult();
for (String wordRes : result) {
System.out.println(wordRes);
}
It have to return:
abc 2
def 2
ghi 1
I have no idea how to handle that.
Now only shows:
abc
def
ghi
I have no idea how to change this method getResult to return with the value of the hashmap as well without changing the first main code.
public List<String> getResult() {
List<String> keyList = new ArrayList<String>(list.keySet());
return keyList;
}
The hashmap is: {abc=2, def=2, ghi=1}
And list: Map<String, Integer> list = new HashMap<String, Integer>();
Please help me if you know any resolution.
I think that now that you have learned about keySet and valueSet, your next task is to learn about entrySet. That's a collection of Map.Entry<K,V> items, which are in turn composed of the key and the value.
That's precisely what you need to complete your task - simply iterate over the entrySet of your Map while adding a concatenation of the value and the key to your result list:
result.add(entry.getKey() + " " + entry.getValue());
Note that if you use a regular HashMap, the items in the result would not be arranged in any particular order.
You need to change this line:
List<String> keyList = new ArrayList<String>(list.keySet());
to:
//first create the new List
List<String> keyList = new List<String>();
//iterate through the map and insert the key + ' ' + value as text
foreach(string item in list.keySet())
{
keyList.add(item+' '+list[item]);
}
return keyList;
I haven't written java in a while so compiler errors might appear, but the idea should work
Well simplest way make an ArrayList and add as #dasblinkenlight said...
Iterator<?> it = list.entrySet().iterator();
while (it.hasNext()) {
#SuppressWarnings("rawtypes")
Map.Entry maps = (Map.Entry) it.next();
lista.add(maps.getKey() + " " + maps.getValue());
}
}
public List<String> getResult() {
List<String> temp = lista;
return temp;
}
If you want to iterate over map entries in order of keys, use an ordered map:
Map<String, Integer> map = new TreeMap<String, Integer>();
Then add your entries, and to print:
for (Map.Entry<String, Ibteger> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}

Printing HashMap In Java

I have a HashMap:
private HashMap<TypeKey, TypeValue> example = new HashMap<TypeKey, TypeValue>();
Now I would like to run through all the values and print them.
I wrote this:
for (TypeValue name : this.example.keySet()) {
System.out.println(name);
}
It doesn't seem to work.
What is the problem?
EDIT:
Another question: Is this collection zero based? I mean if it has 1 key and value will the size be 0 or 1?
keySet() only returns a set of keys from your hash map, you should iterate this key set and the get the value from the hash map using these keys.
In your example, the type of the hash map's key is TypeKey, but you specified TypeValue in your generic for-loop, so it cannot be compiled. You should change it to:
for (TypeKey name: example.keySet()) {
String key = name.toString();
String value = example.get(name).toString();
System.out.println(key + " " + value);
}
Update for Java8:
example.entrySet().forEach(entry -> {
System.out.println(entry.getKey() + " " + entry.getValue());
});
If you don't require to print key value and just need the hash map value, you can use others' suggestions.
Another question: Is this collection is zero base? I mean if it has 1 key and value will it size be 0 or 1?
The collection returned from keySet() is a Set. You cannot get the value from a set using an index, so it is not a question of whether it is zero-based or one-based. If your hash map has one key, the keySet() returned will have one entry inside, and its size will be 1.
A simple way to see the key value pairs:
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
System.out.println(Arrays.asList(map)); // method 1
System.out.println(Collections.singletonList(map)); // method 2
Both method 1 and method 2 output this:
[{b=2, a=1}]
Assuming you have a Map<KeyType, ValueType>, you can print it like this:
for (Map.Entry<KeyType, ValueType> entry : map.entrySet()) {
System.out.println(entry.getKey()+" : "+entry.getValue());
}
To print both key and value, use the following:
for (Object objectName : example.keySet()) {
System.out.println(objectName);
System.out.println(example.get(objectName));
}
You have several options
Get map.values() , which gets the values, not the keys
Get the map.entrySet() which has both
Get the keySet() and for each key call map.get(key)
For me this simple one line worked well:
Arrays.toString(map.entrySet().toArray())
A simple print statement with the variable name which contains the reference of the Hash Map would do :
HashMap<K,V> HM = new HashMap<>(); //empty
System.out.println(HM); //prints key value pairs enclosed in {}
This works because the toString()method is already over-ridden in the AbstractMap class which is extended by the HashMap Class
More information from the documentation
Returns a string representation of this map. The string representation consists of a list of key-value mappings in the order returned by the map's entrySet view's iterator, enclosed in braces ("{}"). Adjacent mappings are separated by the characters ", " (comma and space). Each key-value mapping is rendered as the key followed by an equals sign ("=") followed by the associated value. Keys and values are converted to strings as by String.valueOf(Object).
map.forEach((key, value) -> System.out.println(key + " " + value));
Using java 8 features
You want the value set, not the key set:
for (TypeValue name: this.example.values()) {
System.out.println(name);
}
The code you give wouldn't even compile, which may be worth mentioning in future questions - "doesn't seem to work" is a bit vague!
Worth mentioning Java 8 approach, using BiConsumer and lambda functions:
BiConsumer<TypeKey, TypeValue> consumer = (o1, o2) ->
System.out.println(o1 + ", " + o2);
example.forEach(consumer);
Assuming that you've overridden toString method of the two types if needed.
Java 8 new feature forEach style
import java.util.HashMap;
public class PrintMap {
public static void main(String[] args) {
HashMap<String, Integer> example = new HashMap<>();
example.put("a", 1);
example.put("b", 2);
example.put("c", 3);
example.put("d", 5);
example.forEach((key, value) -> System.out.println(key + " : " + value));
// Output:
// a : 1
// b : 2
// c : 3
// d : 5
}
}
Useful to quickly print entries in a HashMap
System.out.println(Arrays.toString(map.entrySet().toArray()));
I did it using String map (if you're working with String Map).
for (Object obj : dados.entrySet()) {
Map.Entry<String, String> entry = (Map.Entry) obj;
System.out.print("Key: " + entry.getKey());
System.out.println(", Value: " + entry.getValue());
}
Using java 8 feature:
map.forEach((key, value) -> System.out.println(key + " : " + value));
Using Map.Entry you can print like this:
for(Map.Entry entry:map.entrySet())
{
System.out.print(entry.getKey() + " : " + entry.getValue());
}
Traditional way to get all keys and values from the map, you have to follow this sequence:
Convert HashMap to MapSet to get set of entries in Map with entryset() method.: Set dataset = map.entrySet();
Get the iterator of this set: Iterator it = dataset.iterator();
Get Map.Entry from the iterator: Map.Entry entry = it.next();
use getKey() and getValue() methods of the Map.Entry to retrive keys and values.
Set dataset = (Set) map.entrySet();
Iterator it = dataset.iterator();
while(it.hasNext()){
Map.Entry entry = mapIterator.next();
System.out.print(entry.getKey() + " : " + entry.getValue());
}
Print a Map using java 8
Map<Long, String> productIdAndTypeMapping = new LinkedHashMap<>();
productIdAndTypeMapping.forEach((k, v) -> log.info("Product Type Key: " + k + ": Value: " + v));
If the map holds a collection as value, the other answers require additional effort to convert them as strings, such as Arrays.deepToString(value.toArray()) (if its a map of list values), etc.
I faced these issues quite often and came across the generic function to print all objects using ObjectMappers. This is quite handy at all the places, especially during experimenting things, and I would recommend you to choose this way.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public static String convertObjectAsString(Object object) {
String s = "";
ObjectMapper om = new ObjectMapper();
try {
om.enable(SerializationFeature.INDENT_OUTPUT);
s = om.writeValueAsString(object);
} catch (Exception e) {
log.error("error converting object to string - " + e);
}
return s;
}
You can use Entry class to read HashMap easily.
for(Map.Entry<TypeKey, TypeKey> temp : example.entrySet()){
System.out.println(temp.getValue()); // Or something as per temp defination. can be used
}

Categories