Get the lowest number from an Array [duplicate] - java

This question already has answers here:
Finding the smallest and second smallest value in an array Java
(3 answers)
Closed 8 years ago.
For my programming class I need to write a method where the code prints the fastest and the second fastest runner.
This is what I've got:
import java.util.Arrays;
class Marathon {
public static void main (String[] arguments){ `
`String[] names ={
"Alex", "Clair", "Sarah", "Andy", "Anna", "Bob"
};
int[] times ={
341, 273, 278, 329, 445, 402,
};
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]+ ": " + times[i]);
}
}
}
How do I get it to show only the fastest person (lowest number) and the second fastest person (second lowest number).

Here's one way to find the fastest runner
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
class Marathon {
public static void main (String[] arguments){
HashMap<String, Integer>namez = new HashMap<String, Integer>();
namez.put("Alex", 341 );
namez.put("Clair",273 );
namez.put("Sarah",278);
namez.put("Andy",329);
namez.put("Anna",445 );
namez.put("Bob",402);
Integer min = Collections.min(namez.values());
namez.containsValue(min);
for (Entry<String, Integer>entry: namez.entrySet()){
if(entry.getValue()==min){
System.out.println(entry.getKey()+": "+entry.getValue());
String key = entry.getKey();
}
}
}
}
EDIT: Here is actually the way that finds fastest and the second fastest person from your list. It only outputs their names, which are Clair and Sarah. I hope it helps.
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
class Marathon {
public static void main (String[] arguments){
HashMap<Integer, String>namez = new HashMap<Integer, String>();
namez.put(341,"Alex");
namez.put(273,"Clair");
namez.put(278, "Sarah");
namez.put(329,"Andy");
namez.put(445,"Anna");
namez.put(402, "Bob");
ArrayList<Integer> timez = new ArrayList<Integer>();
timez.add(341);
timez.add(273);
timez.add(278);
timez.add(329);
timez.add(445);
timez.add(402);
Collections.sort(timez);
System.out.println(namez.get(timez.get(0)));
System.out.println(namez.get(timez.get(1)));
}
}

This is probably the most compact way to do it:
import java.util.*;
public class Main {
public static void main(String[] args) {
//Create the mapping:
TreeMap<Integer, String> timeToNameMapping = new TreeMap<Integer,String>();
timeToNameMapping.put(341, "Alex");
timeToNameMapping.put(273, "Clair");
timeToNameMapping.put(278, "Sarah");
timeToNameMapping.put(329, "Andy");
timeToNameMapping.put(445, "Anna");
timeToNameMapping.put(402, "Bob");
//Get the keys from the above mapping.
//Since it is a TreeMap, the keys are sorted
List<Integer> times = new ArrayList<>(timeToNameMapping.keySet());
//Print the result
System.out.println("First: " + timeToNameMapping.get(times.get(0)));
System.out.println("Second: " + timeToNameMapping.get(times.get(1)));
}
}
Output:
First: Clair
Second: Sarah
Explanation:
I am using the reverse mapping, as this enables you to just sort all the keys, and then map the first two elements of the sorted list to the names in the TreeMap (given a runtime the TreeMap above will tell you the name of the runner for that time). TreeMaps are already ordered, but since they keys in the Map are in a TreeSet we cannot use index on it to get the two first elements. That is why I convert the keySet() to an ArrayList (which allows for indexing).
To elaborate on dictionaries (Maps):
Generally when using Lists you use the get() method to get a specific element. For Lists like ArrayList and LinkedList the get() method takes an integer (an index value) and returns the element that are at that position in the list.
Maps are a bit different: Maps make a correlation between a key and a value. In the above example if I give the map the key 341, then it will give me the value "Alex". The get() method on a Map therefore takes a key of type K (in this case an Integer, but it can be any kind of object actually) and returns a value of type V (in this case a String, but can also be any object). The type of the key and value are determined when creating the Map (in this case K, V = Integer, String). The concept of telling the map exactly what types are being used are called generics.

You want to sort the array first and then print out the first two in the array. Because it is for your class I wont give you the code that you need but I gave you the perfect hint all you have to do is google how to sort the array and call on first two. Google Keyswords "Java Sort Array"

Related

How can I retrieve all values for a column key in a multidimensional ArrayTable?

I'm trying to retrieve all matrix values from a multidimensional array table, using Google's Guava tables package. Right now, I can get all elements for a specific column key as follows:
import java.util.List;
import java.util.Map;
import com.google.common.collect.ArrayTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
public class createMatrixTable {
public static void main(String[] args) {
// Setup table just like a matrix in R
List<String> universityRowTable = Lists.newArrayList("Mumbai", "Harvard");
List<String> courseColumnTables = Lists.newArrayList("Chemical", "IT", "Electrical");
Table<String, String, Integer> universityCourseSeatTable = ArrayTable.create(universityRowTable, courseColumnTables);
// Populate the values of the table directly
universityCourseSeatTable.put("Mumbai", "Chemical", 120);
universityCourseSeatTable.put("Mumbai", "IT", 60);
universityCourseSeatTable.put("Harvard", "Electrical", 60);
universityCourseSeatTable.put("Harvard", "IT", 120);
// Get all of the elements of a specific column
Map<String, Integer> courseSeatMap = universityCourseSeatTable.column("IT");
// Print out those elements
System.out.println(courseSeatMap);
}
}
Which returns the following in the console:
{Mumbai=60, Harvard=120}
How can I assign just the values (60 and 120) to an array variable without the row keys?
List<Integer> courseSeatValuesIT = new ArrayList<Integer>();
Such that if I were to print the list, it would return the following:
// Print out the variable with just values
System.out.println(courseSeatValuesIT);
[60,120]
Thanks to any Java rock stars who take the time to help out a new guy!!
If you want only values from specified column, just use .values() on returned map:
Collection<Integer> courseSeatValuesIT = courseSeatMap.values();
System.out.println(courseSeatValuesIT);
If you need list, copy it to new one:
List<Integer> courseSeatValuesIT = new ArrayList<>(courseSeatMap.values());
Note that you're using ArrayTable here, which is fixed-size and requires allowed row and column keys must be supplied when the table is created. If you ever want to add new row / column (ex. "Oxford" -> "Law" -> value), you should use HashBasedTable in first place.

Count same lines in a file, JAVA

I have a text file which has lines of animals, who occur on this list from 1 to n times. I need to read this text file, count all the separate animal occurences, sort them from highest to lowest and put them in a jtable.
For example, the text file looks like this:
dog
sheep
cat
horse
cat
tiger
cat
cat
tiger
I need to count all the same occurences like so:
dog 1
sheep 1
cat 4
horse 1
tiger 2
And then sort them from highest to lowest and somehow put them into a table, so that would be:
Animal name: count
cat 4
tiger 2
dog 1
sheep 1
horse 1
So, for now my specific question is how can i count the matches for all the separate animals?
Thanks for the help!
EDIT
The answer provided by Vishal Kamat, has worked, my animals and their occurences have been counted with this code:
java hashmap word count from a text file
Now, I just need to put all this information to a new jtable
Just use the switch-case. You can use a counter for each animal. Or use an arrayList where you can store the amount of each animal...
String line = reader.readLine();
while (line != null) {
switch (line) {
case "cat":
catCounter++;
break;
case "dog":
dogCounter++;
break;
case "horse":
horseCounter++;
break;
case "tiger":
tigerCounter++;
break;
case "sheep":
sheepCounter++;
break;
default:
break;
}
}
Unfortunately I'm not able to write and test a code, but I am able to give you a path to do the thing you want.
You can use Regex for matching how many times, let's say "cat" was mentioned in the text file.
Perhaps this would help: http://code.runnable.com/UqUJWzqM7L8-AAFT/how-to-count-the-number-of-matching-string-in-java-for-regex
I did not write the code, credits to Mirang.
You can have a Map<String, Integer> where key would be the animal name and count would be the occurances so far. Everytime you read an animal, get the value from the map and increment it. Finally you can sort the Map using the integer value of the count and store in the table.
You can try this.if it is convenient to you.
HashMap map=new HashMap();
HashSet set=new HashSet();
FileInputStream fis=new FileInputStream(file);
StreamTokenizer st=new StreamTokenizer(fis);
while(st.nextToken()!=StreamTokenizer.TT_EOF){
Integer count=1;
String s;
switch(st.ttype)
{
case StreamTokenizer.TT_WORD:
s=st.sval;
if(map.containsKey(s))
{
count=(Integer)map.get(s);
count++;
map.put(s,count);
set.add(s);
}
else
{
map.put(s,count);
set.add(s);
}
break;
}
}
//now you have a collection of words with their frequency.it will automatically sort numeric values
System.out.println("frequency of each word in file");
Iterator iter=set.iterator();//get all the keys from the HashSet
//display them with help of Iterator interface
while(iter.hasNext())
{
String s=(String)iter.next();
Integer count=(Integer)map.get(s);
System.out.println("frequency of "+s+" : "+count);
}
Most of the answers here are either too complicated or don't implement frequency distribution properly. Following is my solution:
Map<String, Integer> frequency = new HashMap<>();
try (Scanner scanner = new Scanner(new File("path/to/file"), "UTF-8")) {
while (scanner.hasNext()) {
String temp = scanner.nextLine();
if(frequency.containsKey(temp)) {
Integer count = frequency.get(temp);
frequency.put(temp, Integer.sum(count, 1));
} else {
frequency.put(temp, 1);
}
}
}
The key of the Map contains the animal name and value (which is an Integer) contains the occurrences of the animal names read so far. After each iteration, check if the animal name is in the key. If yes, increment its value. Otherwise, put a new key-value pair with the value as 1. Once the Map has been populated, you can use it as you please.
You can do this with Java 8 Streams. This solution is compact and quite expressive. It creates a Stream of lines read from the file. Each unique line becomes a group, it counts the entries in each group, and then sorts the groups by their value, in descending order.
Now since you want to put these in a JTable, you need a two dimentional array.
package com.test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.JTable;
public class TestCount {
public static void main(String args[]) throws URISyntaxException, IOException {
// for absolute path use: Paths.get("/path/to/animals.txt")
try (Stream<String> stream = Files.lines(Paths.get(TestCount.class.getClassLoader().getResource("animals").toURI()))) {
Object[][] data = stream
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.map((entry) -> new Object[] { entry.getKey(), entry.getValue() })
.toArray(Object[][]::new);
// print the data
for (Object[] row : data) {
System.out.println(Arrays.toString(row));
}
// create the JTable
new JTable(data, new String[] { "animal", "count" });
}
}
}
If you already have a sorted Map you can covert to a two dimensional array like so:
Object[][] data = m1.entrySet().stream()
.map((entry) -> new Object[] { entry.getKey(), entry.getValue() })
.toArray(Object[][]::new);

How can Boolean/boolean serve as the key of a HashMap in Java?

I have an interview question that asks if Boolean can serve as the key of a HashMap in Java. I wasn't sure how this was possible, and would like an explanation.
It is also unclear if boolean or Boolean was meant in this question. Perhaps both should be handled in an answer.
Of course you can:
Map<Boolean,MyType> myMap = new HashMap<Boolean,MyType>();
myMap.put(true, newValue); // Write
MyType t = myMap.get(boolKey); // Read
Autoboxing makes your job very simple - you don't even need to convert boolean to Boolean.
However, why bother with a map, when boolean has only two possible values? An array of two items and a simple conditional would perform better:
MyType[] myArrayMap = new MyType[2];
myArrayMap[key ? 1 : 0] = newValue; // Write
MyType t = myArrayMap[key ? 1 : 0]; // Read
If it's about the Java class java.util.HashMap<K,V> you cannot, because boolean is a primitive type. You need to use classes such as Boolean
You can do that.For instance
Map<Boolean, String> selectedIds = new HashMap<Boolean, String>();
Usage ??
selectedIds.put(Boolean.TRUE, "stack");
selectedIds.put(Boolean.FALSE, "nostack");
That's a great (and pretty funny!) question. You're only going to have two items, but you can mash multiple items into each value. For example:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
<P>{#code java BooleanKeyedMapXmpl}</P>
**/
public class BooleanKeyedMapXmpl {
public static final void main(String[] igno_red) {
System.out.println("<Boolean,String>:");
Map<Boolean,String> mbs = new TreeMap<Boolean,String>();
mbs.put(true, "hello");
mbs.put(false, "goodbye");
System.out.println("true: " + mbs.get(true));
System.out.println("false: " + mbs.get(false));
System.out.println();
System.out.println("<Boolean,ArrayList<String>>:");
Map<Boolean,List<String>> mbls = new TreeMap<Boolean,List<String>>();
mbls.put(true, new ArrayList<String>());
mbls.put(false, new ArrayList<String>());
List<String> lsTrue = mbls.get(true);
lsTrue.add("hello1");
lsTrue.add("hello2");
lsTrue.add("hello3");
lsTrue.add("hello4");
lsTrue.add("hello5");
List<String> lsFalse = mbls.get(false);
lsFalse.add("goodbye1");
lsFalse.add("goodbye2");
lsFalse.add("goodbye3");
lsFalse.add("goodbye4");
lsFalse.add("goodbye5");
System.out.println("true: " + Arrays.deepToString(lsTrue.toArray()));
System.out.println("false: " + Arrays.deepToString(lsFalse.toArray()));
}
}
Output:
[C:\java_code\]java BooleanKeyedMapXmpl
<Boolean,String>:
true: hello
false: goodbye
<Boolean,ArrayList<String>>:
true: [hello1, hello2, hello3, hello4, hello5]
false: [goodbye1, goodbye2, goodbye3, goodbye4, goodbye5]
Yes, if you mean Boolean, with a capital B. A HashMap can have any type as a key. If only Booleans are allowed, your map will only have two possible keys:
HashMap<Boolean, ?> map = new HashMap();
map.put(Boolean.TRUE, someObject);
map.put(Boolean.FALSE, someOtherObject);
...
Yes. Boolean primitives have a Boolean wrapper class aptly named Boolean. As always, the API is your best friend: http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html But like crush said above, your map would then only have two entries, which seems strange.
Obviously you can.
Map<Boolean, String> myMap = new HashMap<Boolean, String>();
myMap.put(true, "A");
myMap.put(false, "D");

Alphabetize a HashMap of Characters

I have a program that takes the number of instances of a character in a string and then puts them into a HashMap. I have it working, but how do I alphabetize the HashMap. Here is my code:
import java.util.*;
import java.lang.*;
import javax.swing.JOptionPane;
import java.io.*;
public class CharacterCount
{
public static void main(String args[])
{
{
String s = JOptionPane.showInputDialog("Enter in any text.");
String str = s.replaceAll("[., ]", "");
String[] splitted = str.split("");
HashMap hm = new HashMap();
for (int i = 0; i < splitted.length; i++) {
if (!hm.containsKey(splitted[i])) {
hm.put(splitted[i], 1);
} else {
hm.put(splitted[i], (Integer) hm.get(splitted[i]) + 1);
}
}
for (Object word : hm.keySet()) {
if (word.equals("")) {
System.out.println("Spaces: " + (Integer) hm.get(word));
}
else {
System.out.println(word + ": " + (Integer) hm.get(word));
}
}
}
}
}
What do I need to add to make it alphabetize/reorganize the HashMap?
An HashMap is, by default, unsorted. This because its implementation can't rely on order of elements.
If you need a sorted map then you will have to look into a TreeMap which supplies the same interface as a HashMap but it's inherently sorted on keys according to their natural ordering (or a custom Comparator). Mind that a TreeMap doesn't allow ordering on values, so if you need to sort your data by value then you will have to build your own sorted collection.
This is usually done by taking the Map.Entry<K,V> entrySet() and then build a new SortedSet by following your ordering rules.
Most maps, including HashMap, make no promises about order of contents. Consider SortedMap, or maintaining both a hash map and a sorted list in parallel.
Difference between HashMap, LinkedHashMap and TreeMap

Store associative array of strings with length as keys

I have this input:
5
it
your
reality
real
our
First line is number of strings comming after. And i should store it this way (pseudocode):
associative_array = [ 2 => ['it'], 3 => ['our'], 4 => ['real', 'your'], 7 => ['reality']]
As you can see the keys of associative array are the length of strings stored in inner array.
So how can i do this in java ? I came from php world, so if you will compare it with php, it will be very well.
MultiMap<Integer, String> m = new MultiHashMap<Integer, String>();
for(String item : originalCollection) {
m.put(item.length(), item);
}
djechlin already posted a better version, but here's a complete standalone example using just JDK classes:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class Main {
public static void main(String[] args) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String firstLine = reader.readLine();
int numOfRowsToFollow = Integer.parseInt(firstLine);
Map<Integer,Set<String>> stringsByLength = new HashMap<>(numOfRowsToFollow); //worst-case size
for (int i=0; i<numOfRowsToFollow; i++) {
String line = reader.readLine();
int length = line.length();
Set<String> alreadyUnderThatLength = stringsByLength.get(length); //int boxed to Integer
if (alreadyUnderThatLength==null) {
alreadyUnderThatLength = new HashSet<>();
stringsByLength.put(length, alreadyUnderThatLength);
}
alreadyUnderThatLength.add(line);
}
System.out.println("results: "+stringsByLength);
}
}
its output looks like this:
3
bob
bart
brett
results: {4=[bart], 5=[brett], 3=[bob]}
Java doesn't have associative arrays. But it does have Hashmaps, which mostly accomplishes the same goal. In your case, you can have multiple values for any given key. So what you could do is make each entry in the Hashmap an array or a collection of some kind. ArrayList is a likely choice. That is:
Hashmap<Integer,ArrayList<String>> words=new HashMap<Integer,ArrayList<String>>();
I'm not going to go through the code to read your list from a file or whatever, that's a different question. But just to give you the idea of how the structure would work, suppose we could hard-code the list. We could do it something like this:
ArrayList<String> set=new ArrayList<String)();
set.add("it");
words.put(Integer.valueOf(2), set);
set.clear();
set.add("your");
set.add("real");
words.put(Integer.valueOf(4), set);
Etc.
In practice, you probably would regularly be adding words to an existing set. I often do that like this:
void addWord(String word)
{
Integer key=Integer.valueOf(word.length());
ArrayList<String> set=words.get(key);
if (set==null)
{
set=new ArrayList<String>();
words.put(key,set);
}
// either way we now have a set
set.add(word);
}
Side note: I often see programmers end a block like this by putting "set" back into the Hashmap, i.e. "words.put(key,set)" at the end. This is unnecessary: it's already there. When you get "set" from the Hashmap, you're getting a reference, not a copy, so any updates you make are just "there", you don't have to put it back.
Disclaimer: This code is off the top of my head. No warranties expressed or implied. I haven't written any Java in a while so I may have syntax errors or wrong function names. :-)
As your key appears to be small integer, you could use a list of lists. In this case the simplest solution is to use a MultiMap like
Map<Integer, Set<String>> stringByLength = new LinkedHashMap<>();
for(String s: strings) {
Integer len = s.length();
Set<String> set = stringByLength.get(s);
if(set == null)
stringsByLength.put(len, set = new LinkedHashSet<>());
set.add(s);
}
private HashMap<Integer, List<String>> map = new HashMap<Integer, List<String>>();
void addStringToMap(String s) {
int length = s.length();
if (map.get(length) == null) {
map.put(length, new ArrayList<String>());
}
map.get(length).add(s);
}

Categories