Get Hashset Key - java

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public static void printNumWordsDiscovered( HashMap<String,Integer> vocab, HashSet<String> dictionary ) {
HashMap <String,Integer> Combine = new HashMap <String,Integer> ();
Iterator iterVoc = vocab.entrySet().iterator();
List<String> Dic = new ArrayList<String>();
int i = 0;
double actual = 0.0;
double token = 0.0;
while(iterVoc.hasNext()){
Map.Entry iterVocE = (Map.Entry)iterVoc.next();
if (dictionary.contains(iterVocE.getKey().toString())){
int Value = (int) iterVocE.getValue();
actual += 1;
token += Value;
Combine.put(iterVocE.getKey().toString(), Value);
}
}
for(String s: dictionary.KeySet()){
if (Combine.contains(dictionary.get(s).toString())){
System.out.println("Dicovered " + dictionary.get(s) + " ( count " + Combine.get(dictionary.get(s)) + " )");
}
}
}
I am trying to iterate through a HashSet and I get errors concerning my .get() method. How do you get a key in a HashSet?

A HashSet is backed by a HashMap. I want to mention this first, because what manouti said isn't exactly true. A HashSet does have a key; you just doesn't explicitly know about the key from outside the HashSet (or rather you don't call it the key, you call it the value outside of the HashSet).
In fact, the key in the internal HashMap is the value you use in HashSet#add(E). The code for HashSet#add(E):
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
where PRESENT is just a dummy object for the value:
private static final Object PRESENT = new Object();
What you want to do, is call the iterator for HashSet to iterate over all the keys. Per the java.util.HashSet#iterator documentation:
Returns an iterator over the elements in this set. The elements are returned in no particular order.
So this is the equivalent of getting the internal HashMap, getting the HashMap#keySet, and then getting an iterator over that. Not that it matters, but that is exactly how the internal code of HashSet actually does it:
public Iterator<E> iterator() {
return map.keySet().iterator();
}
So that might be a little more explanation than you were looking for, but to your issue:
There is no HashSet#get function, there is no HashSet#KeySet function, there is no HashMap#contains function so I recommend you read through the HashSet documentation at http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html and HashMap documentation http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html before going any further. When in doubt, read the documentation. In Java you have the unique benefit of dealing with an API that is very, very well documented. If you choose not to use it, then its wasted.
In order to "get" anything out of a HashSet you have to have the object that results in the same hashCode anyway...so I'm not sure I quite understand the logic for what you are doing. In other words, if you already have the object, you don't need to get it from the HashSet.
Anyway, the last 6 lines of your code can be changed to this:
for(String s: dictionary.iterator()){
if (Combine.containsKey(s)){
System.out.println("Dicovered " + s + " ( count " + Combine.get(s) + " )");
}
}

You can use Iterator of HashSet.
Iterator it = dictionary.iterator();
String element;
while ( it.hasNext() ) {
element = ( String ) it.next();
if ( Combine.contains(element) ){
System.out.println("Dicovered " + element + " ( count " + Combine.get(element) + " )");
}
}
Iterate over HashSet by using iterator method which returns Iterator.
Use Iterator Pattern instead of:
for(String s: dictionary.KeySet()){
if (Combine.contains(dictionary.get(s).toString())){
System.out.println("Dicovered " + dictionary.get(s) + " ( count " + Combine.get(dictionary.get(s)) + " )");
}
}
Good luck!

Related

Java compilation error in this HashMap. Why is the compiler catching an Object being converted into a String?

import java.util.HashMap;
import java.util.TreeMap;
import java.util.Map;
import java.util.Iterator;
import java.util.Set;
public class Maps {
public static void main(String[] args) {
Map mapA = new HashMap();
Map mapB = new TreeMap();
mapA.put("key1", "element 1");
mapA.put("key2", "element 2");
mapA.put("key3", "element 3");
// The three put() calls maps a string value to a string key. You can then
// obtain the value using the key. To do that you use the get() method like this:
String element1 = (String) mapA.get("key1");
// why do I need the type cast on the right?
System.out.println(element1);
//Another examples with maps
Map vehicles = new HashMap();
vehicles.put("BMW", 5);
vehicles.put("Mercedes", 3);
vehicles.put("Audi", 4);
vehicles.put("Ford", 10);
System.out.println("Total vehicles: " + vehicles.size());
for(String key: vehicles.keySet())
System.out.println(key + " - " + vehicles.get(key));
System.out.println();
String searchKey = "Audi";
if (vehicles.containsKey(searchKey))
System.out.println("Found total " + vehicles.get(searchKey) + " "
+ searchKey + " cars!\n");
// clears vehicles
vehicles.clear();
//should equal to 0 now
System.out.println("Vehicle now contains this many vehicles :" + vehicles.size());
// Lets iterate through the keys of this map:
Iterator iterator = mapA.keySet().iterator();
System.out.println(iterator); // How to inspect this? Is it a kind of map?
Map mapC = new HashMap();
while(iterator.hasNext()){
Object key = iterator.next();
Object value = mapA.get(key);
mapC.put(key,value);
} // Is there a better way to take the contents of the iterator and put them in a new map?
System.out.println(mapC);
//create a new hashmap
HashMap hm = new HashMap();
// put elements to the map
hm.put("Zara", new Double(3434.34));
hm.put("Mahnaz", new Double(123.22));
hm.put("Ayan", new Double(1378.00));
hm.put("Daisy", new Double(99.22));
hm.put("Qadir", new Double(-19.08));
//get a set of the entries
// The entrySet( ) method declared by the Map interface returns a Set containing the
// map entries.
Set set = hm.entrySet();
// get an iterator
Iterator i = set.iterator();
// Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.println(i.getClass()); // get the class of i
System.out.println(i instanceof Iterator); // checks to see if i is of class Iterator
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
System.out.println();
// Deposit 1000 into Zara's account
double balance = ((Double)hm.get("Zara")).doubleValue();
hm.put("Zara", new Double(balance + 1000));
System.out.println("Zara's new balance: " +
hm.get("Zara"));
}
}
This is my error:
Maps.java:53: error: incompatible types: Object cannot be converted to
String
for(String key: vehicles.keySet())
My questions are
Why is that error occurring? Why is an object trying to be converted to a string? I thought I had put strings as keys into the vehicles HashMap. What is going on?
Why is the typecast needed in the line:
String element1 = (String) mapA.get("key1");
vehicles.keySet() returns a collection of Object, not String. Just because you put strings in as the keys, the API doesn't change.
One approach would be:
for(Object keyObj: vehicles.keySet())
{
String key = keyObj.toString(); // or cast to (String)
Same issue - get() returns an Object. Just because you used a string, the API is still just an object. Again either cast or use toString.
As has been hinted in various comments, if you use generics the compiler has a much better idea of "what types are where". If you define your map like Map<String,String> mapA = new HashMap<String, String>(); then your original code may work because the compiler knows what the data types in the map are.

Iterating with two iterators

I have two array lists which have a different number of items in them.
The first iteration works well, but when it moves on the the next, nothing happens which I suspect is because the second iterator has no next. Is there anyway to reset it?
Iterator<Integer> itID = ID.iterator();
Iterator<String> itTable = Table.iterator();
Iterator<String> itColumn = Column.iterator();
while(itID.hasNext()){
int i = itID.next();
System.out.println(i);
while(itTable.hasNext()){
String SQL = "select " + itColumn.next() + " from " + itTable.next() + " where id=" + i;
System.out.println(SQL);
}
}
I think the problem is that you have to move inside the first cycle the instantiation of the iterators itTable and itColumn.
Iterator<Integer> itID = ID.iterator();
while (itID.hasNext()) {
// Every time you ask for an iterator, you obtain a new one.
Iterator<String> itTable = Table.iterator();
Iterator<String> itColumn = Column.iterator();
int i = itID.next();
System.out.println(i);
while(itTable.hasNext()){
String SQL = "select " + itColumn.next() + " from " + itTable.next() + " where id=" + i;
System.out.println(SQL);
}
}
So the best way to "reset" an iterator is to ask to the aggregate for a new instance of the iterator itself.
The iterators used in the nested loop should be initialized inside of the first loop so they get reset every time the outer loop iterates.
But you can (and should) just use a for loop to iterate through an ArrayList:
for (int i = 0; i < myList.size(); i++) {
// use myList.get(i)
}
Or just
for (String s : myList) { // Change string to whatever type your list is holding
// use 's'
}
The second loop there is called a for each loop. It is designed for iterating through lists and arrays. For your purpose this one will not work because you're iterating through 2 lists, but I thought I'd bring it up anyway. You should use the first for loop.
A little bit past the scope of the question, but this is my thoughts.
Iterating through two lists which you assume to be the same size, is asking for trouble. If these two values are supposed to be coupled together, then well.. couple them together. The following class can do that:
class SQLField
{
private String tableName;
private String columnName;
public SQLField(String tableName, String columnName) {
this.tableName = tableName;
this.columnName = columnName;
}
public getSelect() {
return "select " + this.columnName + " from " + this.tableName
}
}
This makes the using code:
Iterator<Integer> itID = ID.iterator();
while (itID.hasNext()) {
// Every time you ask for an iterator, you obtain a new one.
Iterator<SQLField> fields = SQLFields.iterator();
int i = itID.next();
System.out.println(i);
for(SQLField field : fields) {
String SQL = field.getSelect() + " where id = " + i;
System.out.println(SQL);
}
}
This is a much better approach in my opinion.

Treemap Entry converted to String types fails

I have two collections where both the keys and the values are strings. I need the collections to be ordered, so I decided to use "TreeMap" to keep the ordering.
I want to:
1) print out the two collections, 'garList' and 'noGarList', respectively;
2) compare each and every element of the first collection with each and every element of the second collection;
3) remove from the first collection ('garList') those elements that appear in the second collection ('noGarList') as well.
I wrote the following code to do these 3 tasks:
public class TryTask_A_copy {
public static void main(String[] args) {
// First collection:
TreeMap<String, String> garList = new TreeMap<>();
// Second collection:
TreeMap<String, String> noGarList = new TreeMap<>();
// Fill the "Properties" obj for 'Gar':
garList.put("Gar_1", "rotura de lunas");
garList.put("Gar_2", "arbitraje de ley");
garList.put("Gar_3", "Adaptación del hogar");
// Fill the "Properties" obj for 'noGar':
noGarList.put("noGar_1", "rotura de lunas");
noGarList.put("noGar_2", "reembolso total");
noGarList.put("noGar_3", "Adaptación del coche");
// Get a set of the entries:
Set garSet = garList.entrySet();
Set noGarSet = noGarList.entrySet();
// Def strings needed for the comparison:
String strGar;
String strNoGar;
// Get an iterator:
Iterator i_gar = garSet.iterator();
Iterator i_noGar = noGarSet.iterator();
// Display 'Gar' elements:
while(i_gar.hasNext()){
String me_Gar = (String)i_gar.next(); // Exception in thread "main" java.lang.ClassCastException: java.util.TreeMap$Entry cannot be cast to java.lang.String
strGar = (String) i_gar.next();
System.out.println(strGar + " : " + garList.get(strGar) + ".");
}
System.out.println();
// Display 'noGar' elements:
while(i_noGar.hasNext()){
String me_noGar = (String)i_noGar.next();
strNoGar = (String) i_noGar.next();
System.out.println(strNoGar + " : " + garList.get(strNoGar) + ".");
}
// Get new iterators:
Iterator itr_gar = garSet.iterator();
Iterator itr_noGar = noGarSet.iterator();
// Compare elements from 'Gar' list with elements from 'noGar' list
// and remove those elements from 'Gar' list that appear in 'noGar' list as well:
while(itr_gar.hasNext()){
strGar = (String) itr_gar.next();
while(itr_noGar.hasNext()){
String str1 = garList.get(strGar);
strNoGar = (String) itr_noGar.next();
String str2 = noGarList.get(strNoGar);
boolean result = str1.equalsIgnoreCase(str2);
System.out.println(strGar + " : " + str1 + ".");
System.out.println(strNoGar + " : " + str2 + ".");
System.out.println(result);
System.out.println();
// if an element appears in both lists, then remove this element from "Gar" list:
if(result != true){
} else {
Object garList_new = garList.remove(strGar);
System.out.println("Removed element: " + garList_new);
System.out.println();
}
}
itr_noGar = noGarSet.iterator();
}
}
}
But I get:
Exception in thread "main" java.lang.ClassCastException:
java.util.TreeMap$Entry cannot be cast to java.lang.String" at line 51
(see comments).
I understand that the elements of my two TreeMap objects are of "Map Entry" type and cannot be converted to "String" type, is that correct?
But then how can I get an ordered collection where both the keys and the values are Strings?
Writing something like garSet.removeAll(noGarSet) does not work because this would imply that both key AND value coincide. But in my case I have some of the values in the two collections coinciding while having different keys.
So I need a solution to the following: have an ordered collection where both keys and values are Strings and where values can be compared and removed.
Can you please help me out with this?
I'm a little unclear on just what you are trying to achieve but if you want to remove based on keys then just do:
garSet.removeAll(noGarSet);
Your code in general seems to be far more complex than it needs to be for what you are trying to achieve. For example to print all the Strings in the Map just do:
for (Entry<String, String> entry: garMap.entrySet()) {
System.out.println(entry.key() + " : " + entry.value() + ".");
}
If you do:
map1.keySet().removeAll(map2.keySet())
then that will remove all the duplicates based on key.
map1.values().removeAll(map2.values())
will remove all duplicates based on value.
map1.entryset().removeAll(map2.entrySet())
will remove all duplicates based on key/value pairs.

Why do my array.size() give wrong value?

I have an instance of ArrayList named array.
When I parse some JSON data it will store it all in array.
When I do a System.out.println(array); it will list a long list of items, around 30, but when I write System.out.println(array.size); it will give the value one.
How come it only gives me the value 1 when the list contains at least 30 values?
My code for this:
public void setLocationName (String name) {
array = new ArrayList<String>();
array.add(name);
System.out.println(array); //This return a long list
System.out.println(array.size()); //But this only return the value 1
}
public String[] getLocationName() {
String tArray[] = null;
for (int i = 0; i < array.size(); i++){
System.out.println(i);
tArray = array.toArray(new String[i]);
}
return tArray;
}
}
The long list :
[Brunnsparken, Göteborg]
[Brunnsgatan, Göteborg]
[Brunnslyckan, Lerum]
[Brunnsbotorget, Göteborg]
[Brunnsnäs, Ulricehamn]
[Brunnshult, Mellerud]
[Brunnsdal, Skövde]
[Brunns skola, Ulricehamn]
[Brunnsgården, Kungälv]
[Brunns kyrka, Ulricehamn]
[Boråsparken, Borås]
[Stadsparken, Ulricehamn]
[Lysekilsparken, Lysekil]
[Mössebergsparken, Falköping]
[Dalaborgsparken, Vänersborg]
[Rösparken, Åmål]
[Lillhagsparken Norra, Göteborg]
[Lillhagsparken Södra, Göteborg]
[Sylte Ryrbäcksparken, Trollhättan]
[Skogstomtsparken, Borås]
[Svinesundsparken, Norge]
[Håjumsparken, Trollhättan]
[Eriksdalsparken, Bollebygd]
[Fridhemsparken, Lidköping]
My result will be that only one item from the list will be returned in the tArray but I wanna return the whole list.
How to solve this?
Java doesn't understand Json and basically what you're doing is add a string to an array
this.array.add(name); ---> add one value to the array, therefore the size is just one
you may need to use a specific Json library to parse the data in to an java arraylist.
regards
Look like you need to parse the String into pairs.
Looks to me like a Map might be the most appropriate structure to store the data in - I presume the first part from the value is unique.
Regex is probably the best approach to parsing the data:
public static void main(String[] args) {
final String data = "[Brunnsparken, Göteborg]\n"
+ "[Brunnsgatan, Göteborg]\n"
+ "[Brunnslyckan, Lerum]\n"
+ "[Brunnsbotorget, Göteborg]\n"
+ "[Brunnsnäs, Ulricehamn]\n"
+ "[Brunnshult, Mellerud]\n"
+ "[Brunnsdal, Skövde]\n"
+ "[Brunns skola, Ulricehamn]\n"
+ "[Brunnsgården, Kungälv]\n"
+ "[Brunns kyrka, Ulricehamn]\n"
+ "[Boråsparken, Borås]\n"
+ "[Stadsparken, Ulricehamn]\n"
+ "[Lysekilsparken, Lysekil]\n"
+ "[Mössebergsparken, Falköping]\n"
+ "[Dalaborgsparken, Vänersborg]\n"
+ "[Rösparken, Åmål]\n"
+ "[Lillhagsparken Norra, Göteborg]\n"
+ "[Lillhagsparken Södra, Göteborg]\n"
+ "[Sylte Ryrbäcksparken, Trollhättan]\n"
+ "[Skogstomtsparken, Borås]\n"
+ "[Svinesundsparken, Norge]\n"
+ "[Håjumsparken, Trollhättan]\n"
+ "[Eriksdalsparken, Bollebygd]\n"
+ "[Fridhemsparken, Lidköping]";
final Pattern pattern = Pattern.compile("\\[([^,]++),\\s++([^\\]]++)\\]");
final Matcher matcher = pattern.matcher(data);
final Map<String, String> items = new TreeMap<>();
while (matcher.find()) {
items.put(matcher.group(1), matcher.group(2));
}
for (final Entry<String, String> entry : items.entrySet()) {
System.out.println(entry);
}
}
Output from this:
Boråsparken=Borås
Brunns kyrka=Ulricehamn
Brunns skola=Ulricehamn
Brunnsbotorget=Göteborg
Brunnsdal=Skövde
Brunnsgatan=Göteborg
Brunnsgården=Kungälv
Brunnshult=Mellerud
Brunnslyckan=Lerum
Brunnsnäs=Ulricehamn
Brunnsparken=Göteborg
Dalaborgsparken=Vänersborg
Eriksdalsparken=Bollebygd
Fridhemsparken=Lidköping
Håjumsparken=Trollhättan
Lillhagsparken Norra=Göteborg
Lillhagsparken Södra=Göteborg
Lysekilsparken=Lysekil
Mössebergsparken=Falköping
Rösparken=Åmål
Skogstomtsparken=Borås
Stadsparken=Ulricehamn
Svinesundsparken=Norge
Sylte Ryrbäcksparken=Trollhättan
You can the access the items by looping (as above) or by getting values from the Map by key. The TreeMap I have used will sort the data by key, you can also use a LinkedHashMap to store the data in insertion order.
You could also store the items in a List of tuple like structures.
public void setLocationName (String name) {
array = new ArrayList<String>();
array.add(name);
System.out.println(array); //This return a long list
System.out.println(array.size()); //But this only return the value 1
}
You are creating a new ArrayList each time you call this method:
array = new ArrayList<String>();
You could just remove the above line, however I suggest you rename the method as this is no longer a setter and you are in fact now adding to an existing list each time you call this method.
I suggest what you want to do is build your List before parsing to the setter, perhaps using a foreach loop (I'm not sure what kind of object you are working with) and simplify your setter (setLocationName) to accomodate.
So it would become:
public void setLocationName(ArrayList<String> names)
{
this.array = names;
System.out.println(array); //This return a long list
System.out.println(array.size()); //But this only return the value 1
}

How to Print treemap in reverse order

In my assignment we are read from a file the text:
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
then count the times each has occured. I've been able to print this map unsorted, then I was able to make a TreeMap and print it in natural order (which is shown below). I don't know how to print in reverse order. I know a way to use a comparator, but I'm a little rusty so I've done what I can. Furthermore, I don't know how to set the comparator up to sort the Treemap into reverse order.
Here's my method to print Unsorted and Naturally sorted:
private static void sortPrintFrequencies(Map<String,Integer> vocabulary, PrintStream output {
Iterator iterator = vocabulary.keySet().iterator();
System.out.println("Unsorted");
while (iterator.hasNext()) {
String key = iterator.next().toString();
String value = vocabulary.get(key).toString();
String times = "times.";
String appears = "appears";
System.out.printf("%35s", key + " " + appears + " " + value + " "+ times);
System.out.println();
}
System.out.println("========================================");
System.out.println("SORTED NATURALLY BY KEY");
TreeMap newVocabulary = new TreeMap(vocabulary);
Iterator iterator2 = newVocabulary.keySet().iterator();
while (iterator2.hasNext()) {
String key = iterator2.next().toString();
String value = newVocabulary.get(key).toString();
String times = "times.";
String appears = "appears";
System.out.printf("%35s", key + " " + appears + " " + value + " "+ times);
System.out.println();
}
TreeMap revVocabulary = new TreeMap(new RevCmpKey());
System.out.println("========================================");
}
Here's my comparator:
import java.util.*;
public class RevCmpKey implements Comparator<String> {
public int compare(String e1, String e2) {
//compareTo in String classs
if(e1.compareTo(e2) <1)return -1;
if(e1.compareTo(e2) >1)return 1;
return 0;
}
}
What about copying your Map into a new one naturally reverse ordered?
new TreeMap<String,Integer>(Collections.reverseOrder())
Short Answer:
Use descendingKeySet or descendingMap.
Long Answer:
Solution 1:
As Oliver correctly mentioned, you can copy the map into a new TreeMap to reach your goal.
However, when using descendingKeySet, you won't need to create a new TreeMap:
treeMap.descendingKeySet()
Here's an example:
private static void printReverseTreeMap(TreeMap<String,Integer> treeMap){
for(String key : treeMap.descendingKeySet()){
System.out.println("value of " + key + " is " + treeMap.get(key));
}
}
Solution 2:
You can also create a new Map in reverse order using descendingMap as well as Collections.reverseOrder():
NavigableMap<String, Integer> reveresedTreeMap = treeMap.descendingMap();
Note that descendingMap returns NavigableMap.
Since String is already comparable, the inverse Comparator is trivial:
public class RevCmpKey implements Comparator<String> {
public int compare(String e1, String e2) {
return - e1.compareTo(e2);
}
}
The other problem is that you are not specifying the values for the Generics; When you construct the TreeMap, you should use
TreeMap<String, Integer> revVocabulary = new TreeMap<String, Integer>(new RevCmpKey());
Then you just call putAll and that is enough
Here you can also prepare a ReverseComparator and use for any class, used in Ordered-Collection :
class ReverseComparator implements Comparator<Comparable<Object>> {
#Override
public int compare(Comparable<Object> o1, Comparable<Object> o2) {
return o2.compareTo( o1 );
}
}
As usually we compare o1 with o2, but for reverse compare o2 with o1
Just try below
private TreeMap<BigInteger, List<TicketingDocumentServiceCouponHistory>> getCpnHistoryMap(
List<TicketingDocumentHistory> tktHistoryList,List<TicketingDocumentServiceCouponTicket> couponList){
TreeMap<BigInteger, List<TicketingDocumentServiceCouponHistory>> cpnHistoryMap = new TreeMap<>(Collections.reverseOrder());
cpnHistoryMap.put(BigInteger.valueOf(Integer.MAX_VALUE), getOcCpnHistoryList(couponList));
tktHistoryList
.stream()
.filter(history -> history.getCode().equals(RVL))
.forEach(history -> cpnHistoryMap.put(history.getSequence(), getCpnHistoryList(cpnHistoryMap, history)));
TreeMap<BigInteger, List<TicketingDocumentServiceCouponHistory>> cpnHistMapInOrder = new TreeMap<>();
cpnHistMapInOrder.putAll(cpnHistoryMap);
return cpnHistMapInOrder;
}

Categories

Resources