Java treeSet in a map - java

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;
}
}
}
}

Related

Why is this "not a statement" in java?

I am very new to Java. My current program loops through a block that asks for users input in the console until the value they type equals done. I want to store each value the user types in an array that is a class property. When I try to append this array, I get an error that says Error:(59, 18) java: not a statement. My code is below. I will point out the line that the error occurs on inside the code. Thanks for your time!
package com.example.java;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Welcome to the musical key calculator!");
System.out.println("Enter your notes one at a time.");
System.out.println("Use uppercase letters A-G and # for sharp and b for flat.(Ex. Eb)");
System.out.println("Remember that E# and B# do not exist in music!");
System.out.println("When you have entered all of your notes, type 'done'");
System.out.println("------------------------------------------------------------------");
boolean finished = false;
Scale YourScale = new Scale();
while(finished == false) {
System.out.print("Enter a note: ");
String note = scanner.nextLine();
if (note == "done'") {
finished = true;
} else {
YourScale.addNote(note);
}
}
if(finished == true){
StringBuilder output = new StringBuilder("Your notes are ");
String[] completedNotes = YourScale.notes;
for (int i = 0; i < completedNotes.length; i++) {
output.append(completedNotes[i] + " ");
}
}
}
public static class Scale {
public String[] notes = {};
public void addNote(String note){
notes[] = note; //Error occurs here.
}
}
}
Java arrays are fixed length, and that isn't how you create (or populate an array). I would prefer to use a Collection like,
public List<String> notes = new ArrayList<>();
public void addNote(String note){
notes.add(note);
}
But, you could use Arrays.copyOf(T[], int) and something like
public String[] notes = new String[0];
public void addNote(String note){
int len = notes.length;
notes = Arrays.copyOf(notes, len + 1);
notes[len] = note;
}
Finally, you do not test String equality with ==
if (note == "done'") {
should be something like
if (note.equals("done")) {
notes is a String array, which means it has many String objects inside. Also you initialize it to an empty array. Arrays should have a fixed size.
//Declare a variable notes, and initialize it as an empty array?
public String[] notes = {};
public void addNote(String note)
{
//This doesn't make sense in java - it's syntax is wrong
notes[] = note;
}
If you want to use arrays this is an example:
//Declare a variable notes, and initialize it as an array of
//specific size (I used 5 as example)
public String[] notes = new String[5];
public void addNote(String note)
{
//Here you should have some short of counter that counts in which
// position of the array you will save 'note' or just run a 'for'
//loop and the first element that is not initialized can get the note
for (int i = 0; i < notes.length; i++)
if (notes[i] == null)
{
notes[i] = note;
break;
}
}
Although this method allows you to save a fixed size, which is not desirable in your case, but nevertheless it uses Array and can help you understand how to use them.
If you want to implement it properly you should use an ArrayList. An ArrayList is an array where you can add new elements and remove them. You can find plenty of documentation online of how to use them.
You are trying to assign a String to a String array. You probably intended to add it to the array.

Sorting String array gives NullPointerException

Hello I have implemented this basic program which should sort out the strings that are inserted however it somehow is failing to insert the strings .
For example if I implement :
TestSort t = new TestSort();
t.i("abc");
t.i("aab");
Can anybody see the error and help me fix this error please ?
Thank you
Here is the code :
public class TestSort {
private int length;
String[] data;
public TestSort() {
length = 0;
}
public void i(String value) {
data[length] = value;
setSorted(data);
length++;
}
public void setSorted(String data[]) {
for(int i = data.length-1; i >= 0; i--) {
for(int j = 0; j < i; j++) {
if(data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
for(int i = 0; i < data.length; i++) {
System.out.print(data[i] +" ");
}
}
}
You don't initialize the array data. So it is set null, and accesses with data[i] will get you an NullPointerException. Even if you initialize this field, it will not work, as Arrays in Java have a fixed size, you have to reallocate the Array, if you insert a new value. You should try a List-implementation instead.
So the code should initialize in the constructor:
data = new ArrayList<String>();
and insertion would change to
data.add(value);
you can change your constructor code as (String array max length can be taken as input parameter):
public testsort()
{
data = new String[10];
length = 0;
}
But if you are not sure with the size of array you can use ArrayList.
You are getting exception because you are comparing with data[j+1] that is still null.
first time when you call
t.i("abc");
there is only one reference in data array that is pointing to String literal "abc" and that is at index 0. index 1 is still referring to null.
first String is already sorted so no need to sort that. if you are having more than one string then you should call setSorted() method.
to solve this you can put your condition in loop as:
if((data[j] != null && data[j+1] != null) &&(data[j].compareTo(data[j + 1]) > -1))
A working example but still: use a List and life is much easier :-)
public class Test {
private int length;
private String[] data;
public Test(int arrayLength) {
// INITIALIZE YOU ARRAY --> No NULLPOINTEREXCEPTION!
data = new String[arrayLength];
length = 0;
}
public void i(String value) {
data[length] = value;
length++;
}
public void setSorted() {
for (int j = 0; j < data.length - 1; j++) {
if (data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
for (String s : data) {
System.out.println(s);
}
}
public static void main(String[] args) {
Test t = new Test(5);
t.i("bbb");
t.i("aaa");
t.i("ccc");
t.i("zzz");
t.i("ddd");
// USE SETSORTED HERE --> else you fill your array with the same elements
t.setSorted();
}
}
The variable 'data' is null since it is nowhere initialized hence giving null pointer exception. Since 'data' is an array and as per the rule whenever an array is defined, it has to be of defined length. for e.g if we consider your case. 'data' can be initialized as :-
String[] data = new String[any numerical value]
the numerical value will be its length i.e. the maximum number of elements it can hold.
Secondly, as per your program statement :-
data[length] = value;
is trying to assign value at data's [length] index which is completely wrong since you haven't defined the length therefore how could you guess the index's value. Therefore your this approaoch is logically wrong.
For such situation i.e. whenever we're unaware about the length of the array, use of ArrayList is suggested. Therefore your program can be re-written by two ways:-
1) Either define the length of the array
String[] data = new String[n];
where n ranges from at least 1 to any positive integer.
2) By using ArrayList
public class Main {
List<String> data;
public Main(){
data = new ArrayList<String>();
}
public static void main(String... q){
Main m = new Main();
m.insertData("abc");
m.insertData("zxy");
m.insertData("aab");
m.insertData("aaa");
m.showData();
}
public void insertData(String str){
data.add(str);
Collections.sort(data);
}
public void showData(){
if(data!=null && !data.isEmpty()){
for(String s : data){
System.out.println(s);
}
}
}
}
output:-
aaa
aab
abc
zxy
Hope this helps.
as Mnementh suggested, the reason for NPE is that you have created the field data of type String[] but you never initialized it.
Other answers have provided every reason on why your code throwing ugly errors; I have just improved your code by replacing your String[] with List<String> so you don't have to worry about the size of your array anymore.
Sorting is also simplified now using Collections.sort().
have a look,
class test1 {
public static void main(String[] args) {
Test sorting = new Test();
sorting.input("abc");
sorting.input("cba");
sorting.input("aab");
sorting.setSorted();
}
}
class Test {
private List<String> data = new ArrayList<String>();
public void input(String value) {data.add(value);}
public void setSorted() {
Collections.sort(data);
for (String current : data) {
System.out.println(current);
}
}
}
if you are using Java 8, then you can use Arrays.parallerSort(), it performs sorting the same way as Collection.sort but with a parallel implementation.
Current sorting implementations provided by the Java Collections Framework > (Collections.sort and Arrays.sort) all perform the
sorting operation sequentially in the calling thread. This enhancement
will offer the same set of sorting operations currently provided by
the Arrays class, but with a parallel implementation that utilizes the
Fork/Join framework. These new API's are still synchronous with regard
to the calling thread as it will not proceed past the sorting
operation until the parallel sort is complete.
to implement it, replace Collections.sort with Arrays.parallelSort in the above code,
Replace,
Collections.sort(data);
with,
Arrays.parallelSort(data.toArray(new String[data.size()]));

Using a data structure to solve this in O(n)

we have sequence of 4 characters (A,B,C and D)that map to numbers form 1 to n.
we define components to be:
Component(k) :
A {cell[k]}
if Color(left_k) = Color(k)
then
A <-- A U Component(left_k)
if Color(right_k) = Color(k)
then
A <-- A U Component(left_k)
return A
there is 3 types of operations(the numbers in list indicate the input):
by giving index it should remove the component in that index(the numbers mapping to characters are fixed)
example : AABBBDA is the string. if index is 3 it should return AADA
by giving index it should rotate the string based on the component on that index(the numbers mapping to characters are fixed)
example : AABBBDA is the string. if index is 3 it should return DABBBAA
it should print the string.
inputs are like:
1 2 --> first operation with index=2
2 3 --> second operation with index=3
3 --> third operation
It's an assignment, happy to get help.
this is what i've tried so far:
public static void main(String[] args)
{
int numberOfOps;
String[] print = new String[30];
List list = new List();
Scanner input = new Scanner(System.in);
int count = input.nextInt();
String colors = new String();
colors = input.next();
for(int i = 0; i < count; i++)
{
list.add(colors.charAt(i));
}
numberOfOps = input.nextInt();
list.printElement();
for (int i = 0; i < numberOfOps; i++)
{
int op = input.nextInt();
if(op == 1)
{
int index = input.nextInt();
char c = list.item[index];
int temp = index;
int prevIndex = index;
int nexIndex = index;
if(index != 0)
{
while (list.item[--index] == c)
{
prevIndex--;
}
while (list.item[++temp] == c)
{
nexIndex++;
}
list.setNext(prevIndex-1, nexIndex+1);
}
else
{
while (list.item[++temp] == c)
{
nexIndex++;
}
list.setNext(prevIndex, nexIndex+1);
}
}
if(op == 2)
{
int index = input.nextInt();
}
if(op == 3)
{
print[i] = list.printElement();
}
}
}
here is my List class:
public class List {
// reference to linked list of items
public static final int MAX_LIST = 20;
public static final int NULL = -1;
public char item[] = new char[MAX_LIST]; // data
public int avail;
public int next[] = new int[MAX_LIST]; // pointer to next item
private int numItems; // number of items in list
public List()
{
int index;
for (index = 0; index < MAX_LIST-1; index++)
next[index] = index + 1;
next[MAX_LIST-1] = NULL;
numItems = 0;
avail = 0;
} // end default constructor
public void add(char e)
{
item[avail] = e;
avail = next[avail];
numItems++;
}
public String printElement()
{
String temp = null;
int index = 0;
while(index<avail)
{
temp += item[index];
System.out.println(item[index]);
index = next[index];
}
return temp;
}
public int size()
{
return numItems;
}
public void setNext(int i, int value)
{
next[i] = value;
}
}
if you test it you'll get, it has lots of problems, such as, I have no idea to do the rotate operation, and it has problem with connecting two components when the middle component has been removed.
This is a difficult question to answer, because the requirements are not properly stated.
For example the first bunch of pseudo-code does not make it clear whether A is a set, a multi-set or a list. The notation (use of curly brackets, and U (union?)) seems to say set ... but the output seems to be a list. Or maybe it is supposed to be a schema for a data structure??
And even the inputs are not clearly described.
But putting that on one side, there is still room for some (hopefully) helpful advice.
Make sure that >>you<< understand the requirements. (I imagine that the real requirements for the assignment are better stated than this, and the details have been "lost in translation".)
I would actually use an array list (or a StringBuilder) rather than a linked list for this. (But a properly implemented linked list ... implementing the List API ... would work.)
But whatever data structure you chose, there is no point in implementing it from scratch ... unless you are specifically required to do that. There are perfectly good list classes in the Java standard libraries. You should reuse them ... rather than attempting to reinvent the wheel (and doing a bad job).
If you are required to implement your own data structure type, then your current attempt is a mess. It looks like a hybrid between an array list and a linked list ... and doesn't succeed in being either. (For example, a decent array list implementation does not need a MAX_LIST, and doesn't have next pointers / indexes. And a linked list does not have any arrays inside it.)

Sorting objects in alphabetical order

For my assignment, I have to create both a method to sort integers and Strings stored in an object class. Keep in mind, I HAD TO USE CASTS. I wanted to use generics, but my teacher INSISTS on me using 1.4.2 (which don't have generics). I can sort time, and for the alphabetical sort, I used my method to sort time and added a compareTo. I played with it a bit, but when I output it, it gives me everything I inputted in the order I inputted it. Not in alphabetical.
Here's the class I created to store input:
public class showInfo
{
String name;
String day;
int time;
}
The following is the method to sort by name!
//method to sort and display info
public static void sortName(){
for(int i = 0; i < show.size() - 1; i++) {
for(int j = 0; j < show.size() - 1; j++){
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
showInfo temp = new showInfo();
temp.name = ((showInfo)show.get(j)).name;
temp.day = ((showInfo)show.get(j)).day;
temp.time = ((showInfo)show.get(j)).time;
((showInfo)show.get(j)).time = ((showInfo)show.get(i)).time;
((showInfo)show.get(j)).day = ((showInfo)show.get(i)).day;
((showInfo)show.get(j)).name = ((showInfo)show.get(i)).name;
((showInfo)show.get(i)).time = temp.time;
((showInfo)show.get(i)).day = temp.day;
((showInfo)show.get(i)).name = temp.name;
}
}
}
Any help would be great! Thanks in advance. :)
(PS. I'm aware I need to change "showInfo" to "ShowInfo", but I'll do it when I'm finished.)
One problem with your code is that you are comparing show.get(i) with show.get(i+1) but then swapping show.get(i) with show.get(j). You should be comparing to show.get(j). Also, the inner loop should go to j < show.size() rather than show.size() - 1. Finally, you can start the inner loop at i + 1 instead of at 0.
Once you determine that you need to swap, you can do much better by simply swapping references in the list, rather than swapping each field:
showInfo tmp = (showInfo)show.get(i);
show.set(i, show.get(j));
show.set(j, tmp);
I assume show is a List and you have to sort by name.
First, make showInfo implement Comparable:
public class showInfo implements Comparable
{
String name;
String day;
int time;
public int compareTo(Object o)
{
showInfo other = (showInfo) o;
return name.compareTo(other.name);
}
}
Then, use `Collections.sort()' on the list:
Collections.sort(show);
You can do something like this....
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class myComparator implements Comparator {
public int compare(Object o1, Object o2) {
return ((o1.toString().charAt(0) > o2.toString().charAt(0)) ? 1 : (o1
.toString().charAt(0) == o2.toString().charAt(0)) ? 0 : -1);
}
}
public class Sample {
/**
* #param args
*/
public static void main(String[] args) {
List l = new ArrayList();
l.add("hello");
l.add("abc");
l.add("World");
l.add("hi");
System.out.println("Before sorting");
for (Object i : l) {
System.out.println(i.toString());
}
Collections.sort(l, new myComparator());
System.out.println("After sorting");
for (Object i : l) {
System.out.println(i.toString());
}
}
}
You are incorrectly using i here :
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
I believe the second i should be j to achieve bubble sort
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(j+1)).name) > 0){
Not sure if this is what you look for, it uses casting insteads of generics, anyway, i hope this will help
pastebin

Java error "Undefined name"

I've tried fixing this I just cant seem to find a solution to this problem. The code is meant to print the prime numbers in a range, but it just returns the error
Static Error: Undefined name 'PrimeNumbers
Would anyone please be able to help me ?
This is my code :
import java.util.*;
public class PrimeNumbers {
private List<Integer> listOfPrimeNumbers; //add a member variable for the ArrayList
public static void main(String args []){
PrimeNumbers primeNumberList = new PrimeNumbers(50);
primeNumberList.print(); //use our new print method
}
public PrimeNumbers (int initialCapacity) {
listOfPrimeNumbers = new ArrayList<Integer>(initialCapacity/2); //initialCapacity/2 is an easy (if not tight) upper bound
long numberOfPrimes = 0; //Initialises variable numberOfPrimes to 0
int start = 2;
boolean[] isPrimeNumber = new boolean[initialCapacity + 1];
for (int i=0;i==initialCapacity;i++) {//setting all values in array of booleans to true
isPrimeNumber[i] = true;
}
while (start != initialCapacity)
{
if (isPrimeNumber[start])
{
listOfPrimeNumbers.add(start);
//add to array list
numberOfPrimes++;
for (int i = start; start < initialCapacity; i+=start)
{
isPrimeNumber[i] = false;
}
}
start++;
}
}
public void print() {
int i = 1;
for (Integer nextPrime:listOfPrimeNumbers) {
System.out.println("the " + i + "th prime is: " + nextPrime);
i++;
}
}
//or just System.out.println(listOfPrimeNumbers);, letting ArrayList's toString do the work. i think it will be in [a,b,c,..,z] format
public List getPrimes() {
return listOfPrimeNumbers;
} //a simple getter isnt a bad idea either, even though we arent using it yet
}
Assuming, you have you code organized like this
./project
PrimeNumbers.java
PrimeNumbers.class
then you cd to ./project and type
java PrimeNumbers
Note - this only works because you didn't declare a package (iaw: you class is in the default package). Usually you have a package declaration and then it looks a bit different.
Bonus
The getter is a good idea, but you should think twice before returning a collection, because this way, you grant the receiver full access to your (internal?) datastructure and he can alter the values of that collection. And you shouldn't declare it with the raw type. Here's a better way to implement it:
public List<Integer> getPrimes() {
return Collections.unmodifiableList(listOfPrimeNumbers);
}
Now the receiver knows that he get's a list of Integer values and can't modify the result.

Categories

Resources