String Array Into HashMap Collection Object - java

I have the following
String[] temp;
which returns
red
blue
green
I would like to add the string array into a collection obejct like HashMap so that I could retrieve values in any class like
HashMap hash = New HashMap();
hash.get("red");
hash.get("blue");
hash.get("green");
How can I do this?
Thanks
Update 1
String str = "red,blue,green";
String[] temp;
String delimiter = ",";
temp = str.split(delimiter);
for (int i = 0; i < temp.length; i++) {
System.out.println(temp[i]);
}
With the above code, I would like to retrieve values based on values in array. E.g. I would like to get the values in from another class by calling hash.get("One"), which would return red, hash.get("Two") which would return blue and so forth.

Map<String, String> hash = new HashMap<String, String>();
for(i = 0 ; i < temp.length(); i++)
{
hash.put(temp[i], temp[i]);
}
Then you can retrieve from map
hash.get (temp[i]);

HashMap<String, String>() map = new HashMap<String, String>();
map.put(temp[i], temp[i]);//here i have considered key as the value itself.. u can use something else //also.

My doubt how I do map temp[i] with red, blue or green?
Using a hash map won't solve this problem directly. Currently you need to write
temp[ someNumberHere ];
so
temp[ 1 ];
yields a String "blue"
If you have a hashMap then instead you might write
myColourMap.get( someNumberHere );
so
myColourMap.get( 1 );
Would yield "blue". In either case you are converting a value to a corresponding string, but you do need to know that "someNumber". If you want "blue" you need to know to ask for number 1.
It may be that what you need is to use nicely named constant values:
public Class Colours {
public static final int RED = 0;
public static final int BLUE = 1;
public static final int GREEN = 1;
// plus either the array of strings or the hashMap
public statuc String getColour(int colourNumber ) {
return myArray[colourNumber]; // or myMap.get(colourNumber)
}
}
Your clients can now write code such as
Colours.getColour( Colour.RED );
[It is better to use enums than just raw ints, but let's not divert from arrays and hashMaps right now].
Now when might you prefer a hashMap instead of an array? Consider that you might have more colours, for example 12695295 might be "light pink" and 16443110 might be "lavender".
Now you really don't want an array with 16,443,110 entries when you are only using perhaps 500 of them. Now a HashMap is a really useful thing
myMap.put( Colour.LAVENDER, 16443110 );
and so on.

Related

How to get few random keys from HashMap

I have a map with titles. I want to print 10 random keys from my hashmap.
For example my map (String, Object) contains 100 pairs: "A, new Object(...)", "B, ...", "C, ..." etc.
I want to get 10 random keys from this map and append it to one string.
So my string should looks like: "A\nD\nB".
A quick way to get random 10 keys without repetition is putting the keys in a list and using Collections.shuffle to shuffle the list.
Map<String, Object> map = ...yourmap
ArrayList<String> keys = new ArrayList<>(map.keySet());
Collections.shuffle(keys);
List<String> randomTenKeys = keys.subList(0, 10);
Creating a list of all keys and shuffling it is not the most efficient thing you can do. You can do it in a single pass with a reservoir sampling algorithm. I haven't looked into it but you can probably find an implementation in some Apache or Guava library.
Joni's answer is quite good and short. But, here is a fully working example if you'd like. I split your problem into two methods - one to return a list of randomly selected keys and another to print keys in whichever way you like. You could combine the two methods into one. But, its better to keep them separate.
import java.util.*;
import java.util.stream.IntStream;
public class Test {
public static void main(String [] args){
Map<String, Object> map = new HashMap<>();
//You can use for loop instead to make a map of String, Integer.
IntStream.rangeClosed(0, 9).forEach(i -> map.put(i +"", i));//Map of 10 numbers.
List<String> keys = getRandomKeys(map, 3);
String allKeys = combineKeys(keys, "\n");
System.out.println(allKeys);
}
public static List<String> getRandomKeys(Map<String, Object> map, int keyCount) {
List<String> keys = new ArrayList<>(map.keySet());
for(int i = 0; i < map.size()-keyCount; i++){
int idx = (int) ( Math.random() * keys.size() );
keys.remove(idx);
}
return keys;
}
public static String combineKeys(List<String> keys, String separator){
String all = "";
for(int i = 0; i < keys.size() - 1; i++){
all = all + keys.get(i) + separator;
}
all += keys.get(keys.size()-1);//last element does not need separator.
return all;
}
}
HashMap Stores the values already in unsorted order it is random.
you can directly use
for(Map.Entry entry : map.entrySet())
str.append(entry.getKey()+" "+entry.getValue());
however if you want new order every time you can shuffle your data.
For Shuffle you need to get all keys in a array or list
Then you can shuffle that list and iterate over that list to get values from hashmap
This is a complementary answer to Joni's answer. Use String:join to join the randomTenKeys.
Given below is Joni's answer:
Map<String, Object> map = ...yourmap
ArrayList<String> keys = new ArrayList<>(map.keySet());
Collections.shuffle(keys);
List<String> randomTenKeys = keys.subList(0, 10);
and the complementary answer is:
String joinedKeys = String.join("\n", randomTenKeys);
Set<String> keys = myMap.keySet();
String combined = "";
for (int i=0; i<10; i++)
{
int random = (int)(Math.random() * keys.size());
String key = keys.get(random);
combined += key + "\n";
keys.remove(random);
}

Java Code optimization : if else to resolve PMD complexity 24 to 0

I have string of array with size already defined and i have to iterate though this array and fill it with fields value of someObject I have . If i do this with if elseif elseif or switch case i get high complexity .. please kindly suggest proper way to do this
I would suggest you to use a map to keep the mapping like this:
private static final Map<Integer, String> MAP_VALUES = new HashMap<Integer, String>();
private static Map<Integer, String> getMapValues(Employe employe){
if(MAP_VALUES.isEmpty()){
MAP_VALUES.put(0, employe.getEmployeeI());
MAP_VALUES.put(1, employe.getEmployeeLastName());
MAP_VALUES.put(2, employe.getEmployeeDivision());
....
}
return MAP_VALUES;
}
public String getValueForEmploye(Employe employe){
String[] value = ...;
for(int i = 0; i < value.length; i++){
value[i] = getMapValues(employe).get(i);
}
}

Using a string to write to an array

Attempting to tidy up code, originally I was using this method of writing to arrays, which is ridiculously long when I have to repeat it 20 times
if (ant.getAntNumber() == 3)
{
numbers3.add(ant.getCol());
numbers3y.add(ant.getRow());
}
if (ant.getAntNumber() == 4)
{
numbers4.add(ant.getCol());
numbers4y.add(ant.getRow());
}
I attempted to use a for loop to do it but I cant figure out how to add to the array using the string value, because it thinks its a string rather than trying to use the array
for (int j = 0; j<maxAnts; j++)
{
String str = "numbers" + j;
String str2 = "numbers" + j + "y";
//this part doesnt work
str.add(ant.getCol());
}
Any suggestions would be helpful
In Java, you cannot use the value of a String object to reference an actual variable name. Java will think you're attempting to to call add on the String object, which doesn't exist and gives you the compiler error you're seeing.
To avoid the repetition, you need to add your Lists to two master lists that you can index.
In your question, you mention arrays, but you call add, so I'm assuming that you're really referring to Lists of some sort.
List<List<Integer>> numbers = new ArrayList<List<Integer>>(20);
List<List<Integer>> numbersy = new ArrayList<List<Integer>>(20);
// Add 20 ArrayList<Integer>s to each of the above lists in a loop here.
Then you can bounds-check ant.getAntNumber() and use it as an index into your master lists.
int antNumber = ant.getAntNumber();
// Make sure it's within range here.
numbers.get(antNumber).add(ant.getCol());
numbersy.get(antNumber).add(ant.getRow());
How about this?
Ant[] aAnt = new Ant[20];
//Fill the ant-array
int[] aColumns = new int[aAnt.length];
int[] aRows = new int[aAnt.length];
for(int i = 0; i < aAnt.length; i++) {
aColumns[i] = aAnt[i].getCol();
aRows[i] = aAnt[i].getRow();
}
or with lists:
List<Integer> columnList = new List<Integer>(aAnt.length);
List<Integer> rowList = new List<Integer>(aAnt.length);
for(Ant ant : aAnt) {
columnList.add(ant.getCol());
rowList.add(ant.getRow());
}
or with a col/row object:
class Coordinate {
public final int yCol;
public final int xRow;
public Coordinate(int y_col, int x_row) {
yCol = y_col;
xRow = x_row;
}
}
//use it with
List<Coordinate> coordinateList = new List<Coordinate>(aAnt.length);
for(Ant ant : aAnt) {
coordinateList.add(ant.getCol(), ant.getRow());
}
A straight-forward port of your code would be to use two Map<Integer, Integer> which store X and Y coordinates. From your code it seems like ant numbers are unique, i.e., we only have to store a single X and Y value per ant number. If you need to store multiple values per ant number, use a List<Integer> as value type of the Map instead.
Map<Integer, Integer> numbersX = new HashMap<Integer, Integer>();
Map<Integer, Integer> numbersY = new HashMap<Integer, Integer>();
for(Ant ant : ants) {
int number = ant.getAntNumber();
numbersX.put(number, ant.getCol());
numbersY.put(number, ant.getRow());
}

Create a 2d Boolean array in Java from table data

I have a .csv file of type:
Event Participant
ConferenceA John
ConferenceA Joe
ConferenceA Mary
ConferenceB John
ConferenceB Ted
ConferenceC Jessica
I would like to create a 2D boolean matrix of the following format:
Event John Joe Mary Ted Jessica
ConferenceA 1 1 1 0 0
ConferenceB 1 0 0 1 0
ConferenceC 0 0 0 0 1
I start by reading in the csv and using it to initialize an ArrayList of type:
AttendaceRecord(String title, String employee)
How can I iterate through this ArrayList to create a boolean matrix like the one above in Java?
This is the easiest way I can think of for you. This answer can certainly be improved or done in a completely different way. I'm taking this approach because you mentioned that you are not completely familiar with Map (I'm also guessing with Set). Anyway let's dive in.
In your AttendanceRecord class you are going to need the following instance variables: two LinkedHashSet and one LinkedHashMap. LinkedHashSet #1 will store all conferences and LinkedHashSet #2 will store all participants. The LinkedHashMap will store the the conferences as keys and participants list as values. The reason for this will be clear in a minute. I'll first explain why you need the LinkedHashSet.
Purpose of LinkedHashSet
Notice in your 2d array, the rows (conferences) and columns (participants) are arranged in the order they were read. Not only that, all duplicates read from the file are gone. To preserve the ordering and eliminate duplicates a LinkedHashSet fits this purpose perfectly. Then, we will have a one-to-one relationship between the row positions and the column positions of the 2d array and each LinkedHashSet via their array representation. Let's use Jhon from ConferenceA for example. Jhon will be at position 0 in the array representation of the participant Set and ConferenceA will be at position 0 in the array representation of the conference Set. Not only that, the size of each array will be used to determine the size of your 2d array (2darray[conferenceArrayLength][participantArrayLength])
Purpose of the LinkedHashMap
We need the LinkedHashMap to preserve the ordering of the elements (hence Linked). The elements will be stored internally like this.
ConferenceA :Jhon Joe Mary
ConferenceB :Jhon Ted
ConferenceC :Jessica
We will then iterate through the data structure and send each key value pair to a function which returns the position of each element from each array returned from each LinkedHashSet. As each row and column position is returned, we will add a 1 to that position in the 2d array.
Note: I used an Integer array for my example, substitute as needed.
AttendanceRecord.java
public class AttendanceRecord {
private Map<String, ArrayList> attendanceRecordMap = new LinkedHashMap<String, ArrayList>();
private Set<String> participants = new LinkedHashSet<String>();
private Set<String> conferences = new LinkedHashSet<String>();
public AttendanceRecord() {
}
public Map<String, ArrayList> getAttendanceRecordMap() {
return attendanceRecordMap;
}
public Object[] getParticipantsArray() {
return participants.toArray();
}
public Object[] getConferencesArray() {
return conferences.toArray();
}
public void addToRecord(String title, String employee) {
conferences.add(title);
participants.add(employee);
if (attendanceRecordMap.containsKey(title)) {
ArrayList<String> tempList = attendanceRecordMap.get(title);
tempList.add(employee);
} else {
ArrayList<String> attendees = new ArrayList<String>();
attendees.add(employee);
attendanceRecordMap.put(title, attendees);
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
AttendanceRecord attendanceRecord = new AttendanceRecord();
//There are hardcoded. You will have to substitute with your code
//when you read the file
attendanceRecord.addToRecord("ConferenceA", "Jhon");
attendanceRecord.addToRecord("ConferenceA", "Joe");
attendanceRecord.addToRecord("ConferenceA", "Mary");
attendanceRecord.addToRecord("ConferenceB", "Jhon");
attendanceRecord.addToRecord("ConferenceB", "Ted");
attendanceRecord.addToRecord("ConferenceC", "Jessica");
int[][] jaccardArray = new int[attendanceRecord.getConferencesArray().length][attendanceRecord.getParticipantsArray().length];
setUp2dArray(jaccardArray, attendanceRecord);
print2dArray(jaccardArray);
}
public static void setUp2dArray(int[][] jaccardArray, AttendanceRecord record) {
Map<String, ArrayList> recordMap = record.getAttendanceRecordMap();
for (String key : recordMap.keySet()) {
ArrayList<String> attendees = recordMap.get(key);
for (String attendee : attendees) {
int row = findConferencePosition(key, record.getConferencesArray());
int column = findParticipantPosition(attendee, record.getParticipantsArray());
System.out.println("Row inside " + row + "Col inside " + column);
jaccardArray[row][column] = 1;
}
}
}
public static void print2dArray(int[][] jaccardArray) {
for (int i = 0; i < jaccardArray.length; i++) {
for (int j = 0; j < jaccardArray[i].length; j++) {
System.out.print(jaccardArray[i][j]);
}
System.out.println();
}
}
public static int findParticipantPosition(String employee, Object[] participantArray) {
int position = -1;
for (int i = 0; i < participantArray.length; i++) {
if (employee.equals(participantArray[i].toString())) {
position = i;
break;
}
}
return position;
}
public static int findConferencePosition(String employee, Object[] conferenceArray) {
int position = -1;
for (int i = 0; i < conferenceArray.length; i++) {
if (employee.equals(conferenceArray[i])) {
position = i;
break;
}
}
return position;
}
}
Basically you'll want to start by searching through your input strings to find each of the names (String.contains) and set a boolean array of each field name.
Then you'll make an array of those boolean arrays (or a list, whatever).
Then you simply sort through them, looking for T/F and printing corresponding messages.
I included some very rough pseudocode, assuming I am understanding your problem correctly.
// For first row
List labelStrings[];
labelStrings = {"Event", "John", "Joe", "Mary", "Ted", "Jessica"};
// For the matrix data
// List to iterate horizontally EDIT: Made boolean!
List<Boolean> strList= new ArrayList()<List>;
// List to iterate vertically
List<List> = listList new ArrayList()<List>;
/* for all the entries in AttendanceRecord (watch your spelling, OP)
for all data sets mapping title to employee
add the row data to strList[entry_num] */
for (int i = 0; i < listList.size()-1; i++)
for (int j = 0; j < labelStrings.size()-1; j++)
{
if (i == 0)
System.out.println(strList[j] + "\t\n\n");
else
{
// print listLists[i][j]
}
// iterate row by row (for each horizontal entry in the column of entries)
}
Sorry, I'm just reading through the comments now.
You'll definitely want to arrange your data in a way that is easy to iterate through. Since you have a fixed table size, you could hardcode a boolean array for each entry and then print on validation they were mapped to the event as indicated in your input string.
Try creating a hash map containing
HashMap map = new HashMap<conferenceStr, HashMap<nameStr, int>>()
As you iterate through your ArrayList, you can do something like
innerMap = map.get(conferenceStr)
innerMap.put(nameStr, 1)
of course you'll need some initialization logic, like you can check if innerMap.get(nameStr) exists, if not, iterate over every inner map and innerMap.put(nameStr, 0)
This structure can be used to generate that final 2D boolean matrix.
Elaboration edit:
ArrayList<AttendanceRecord> attendanceList = new ArrayList<AttendanceRecord>();
// populate list with info from the csv (you implied you can do this)
HashMap<String, HashMap<String, Integer>> map = new HashMap<String, HashMap<String, Integer>>();
//map to store every participant, this seems inefficient though
HashMap<String, Integer>> participantMap = new HashMap<String, Integer>();
for (AttendanceRecord record : attendanceList) {
String title = record.getTitle();
String employee = record.getEmployee();
participantMap.put(employee, 0);
HashMap<String, Integer> innerMap = map.get(title);
if (innerMap == null) {
innerMap = new HashMap<String, Integer>();
}
innerMap.put(employee, 1);
}
//now we have all the data we need, it's just about how you want to format it
for example if you wanted to just print out a table like that you could iterate through every element of map doing this:
for (HashMap<String, Integer> innerMap : map.values()) {
for (String employee : participantMap.values()) {
if (innerMap.get(employee)) {
//print 1
}
else
//print 0
}
}

java linkedhashmap iteration

I have two hashmap
LinkedHashMap<String, int[]> val1 = new LinkedHashMap<String, int[]>();
LinkedHashMap<String, int> val2 = new LinkedHashMap<String, int>();
each hashmap has different key and values. I am trying to iterate over both hashmap
at the same time and multiply each value of val1->int[] to val2->int
What is the easiest and fasted way to do it? I have thousands values in both hashmap.
Thanks
You are probably doing it wrong...
First, a HashMap can't store ints, it needs proper objects - like Integer
– An array is an object, although it's hidden behind some syntactic sugar.
Here's how to loop over both maps, if they happens to have the same size,
which is what I think you mean.
Iterator<int[]> expenses = val1.values().iterator();
Iterator<Integer> people = val2.values().iterator();
assert val1.size() == val2.size() : " size mismatch";
while (expenses.hasNext()) {
int[] expensesPerMonth = expenses.next();
int persons = people.next();
// do strange calculation
int strangeSum = 0;
for (int idx = 0; idx < expensesPerMonth.length; idx++) {
strangeSum += persons * expensesPerMonth[idx];
}
System.out.println("strange sum :" + strangeSum);
}
But You should probably go back and rethink how you store your data –
why are you using maps, and whats the key?
Wouldn't it be better to create an object that represents the combination of monthly expenses and number of people, for instance?
AFAIK, a LinkedHashMap has iteration ordering. So, something like this may work:
Iterator myIt1 = val1.entrySet().iterator();
Iterator myIt2 = val2.entrySet().iterator();
while(val1.hasNext() && val2.hasNext()) {
int myarray[] = val1.next();
for(int i = 0; i<myarray.length; i++) {
myarray[i] = myarray[i] * val2.next();
}
}

Categories