I'm using MapDB to store data for an Object (EconomyData).
EconomyData class:
public class EconomyData implements Serializable {
private static final long serialVersionUID = -2148852211944505714L;
private double[] values;
/**
* Constructor.
*/
private EconomyData(double[] start) {
if (start == null) {
this.values = new double[1];
}
this.values = start;
}
public EconomyData() {
this.values = new double[1];
}
/**
* Update the last value.
* #param newValue The new value.
*/
public void update(double newValue) {
this.values[this.values.length - 1] = newValue;
}
/**
* Get the last value.
* #return The last value.
*/
public double getValue() {
return this.values[this.values.length - 1];
}
/**
* Increase the value of the last value.
* #param increase The amount to increase the last value by.
*/
public void increase(double increase) {
this.values[this.values.length - 1] += increase;
}
It's quite simple and I'm storing the data in MapDB like this:
this.economyData = db.hashMap("economyData")
.keySerializer(new SerializerCompressionWrapper<String>(Serializer.STRING))
.valueSerializer(new EconomyData.EconomyDataSerializer())
.createOrOpen();
However, when I try to update the value in the HTreeMap<String, EconomyData> like this.
economyData.get(key).update(30);
When I then run,
economyData.get(key).getValue();
the result is still the default value (0).
I thought the HTreeMap#get method returns a reference to the object and so editing the value[] inside the EconomyData object would update it in the map but it doesn't seem to be doing that. What am I doing wrong?
I new in Java and trying to run some tests. I cannot use the .getLast() function as its showing error and also cannot seem to create the method. What am I doing wrong.
Here is my partial code. I am trying to create the getLast method which is failing.
Here is the error The type of the expression must be an array type but it resolved to ListOfNVersion03PartA.
*/
public class ListOfNVersion03PartA
{
private int thisNumber; // the number stored in this node
private ListOfNVersion03PartA next; // forms a linked list of objects
private final int nodeID; // a unique ID for each object in the list
private static int nodeCount = 0; // the number of list objects that have been created
/**
* #param num the value to be stored in this object
*/
public ListOfNVersion03PartA(int num)
{
thisNumber = num;
next = null;
++nodeCount;
nodeID = nodeCount;
} // constructor(int num)
/**
* #param num the multiple values to be stored in the list, in that order
*/
public ListOfNVersion03PartA(int [] num)
{
this(num[0]); // in this context, "this" invokes the other constructor
for (int i=1 ; i<num.length ; ++i)
insertLast(num[i]);
} // constructor(int [] num)
/**
* #return the number of elements stored in this list
*/
public int getListSize()
{
return nodeCount;
} // method getListSize
/**
* #return the last element in the list
*/
public int getLast()
{
int y = next[nodeCount-1];
return y;
} // method getLast
/**
* prints this object
*/
public void printNode()
{
System.out.print("[" + nodeID + "," + thisNumber + "]->");
} // method printListNode
/**
* prints the tail of a list
*/
private void printListTail()
{
printNode();
if ( next != null )
next.printListTail();
} // method printListTail
/**
* prints the contents of the list, in order from first to last
*/
public void printList()
{
printNode();
if ( next != null )
next.printListTail();
} // method printList
/**
* This method is NOT examinable in this test.
*
* prints the contents of the list, in order from first to last, and
* then moves the cursor to the next line
*/
public void printlnList()
{
printList();
System.out.println();
} // method printlnList
/**
* #return the number of times the element occurs in the list
*
* #param element the element to be counted
*/
public int countElement(int element)
{
return 999;
} // method countElement
/**
* #return the number of times the replacement was made
*
* #param replaceThis the element to be replaced
* #param withThis the replacement
*/
public int replaceAll(int replaceThis, int withThis)
{
return 999;
} // method replaceAll
/**
* #return a reference to the first object in the list that contains the parameter value, or null if it is not found
*
* #param findThis the value to be found
*/
public ListOfNVersion03PartA findUnSorted(int findThis)
{
// This algorithm is known as "linear search"
if ( thisNumber == findThis )
return this;
if ( next != null )
return next.findUnSorted(findThis);
return null;
} // method findUnSorted
/**
* #return the reference to the object containing the smallest element in the list
*/
public ListOfNVersion03PartA minRef()
{
// add and/or modify code to complete the method
ListOfNVersion03PartA minOfTail;
if ( next == null )
return this;
minOfTail = next.minRef();
if ( thisNumber <= minOfTail.thisNumber )
return this;
else
return minOfTail;
} // method minRef
/**
* Inserts an element in the last position. The pre-existing elements in the
* list are unaffected.
*
* #param newElement the element to be inserted
*/
public void insertLast(int newElement)
{
if ( next == null )
next = new ListOfNVersion03PartA(newElement);
else
next.insertLast(newElement);
} // method insertLast
} // class ListOfNVersion03PartA
This question already has answers here:
How to override toString() properly in Java?
(15 answers)
Closed 4 years ago.
I have been provided with an object and several methods to work with it. I am having a tough time printing the string that I am assigning to the variables. At the moment, I am unsure if I assigning new values at all and I am unable to print any values. Previous iterations have only printed references.
Question: Am I assigning new string values? How do I print a string with the given methods?
Here is the code I was provided
public class Team implements Comparable<Team> {
public String toString(String team, int wins) {
return team + ": " + wins;
}
// Data fields
private String name;
private int winCount;
Team() {
name = "Sooners";
winCount = 1;
}
Team(String inputName) {
name = inputName;
winCount = 1;
}
Team(String inputName, int inputWinCount) {
name = inputName;
winCount = inputWinCount;
}
// ----------------------------------------------------
// Getters and Setters
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the winCount
*/
public int getWinCount() {
return winCount;
}
/**
* #param winCount
* the winCount to set
*/
public void setWinCount(int winCount) {
this.winCount = winCount;
}
/**
* Increments the winCount variable by one for this Team
*/
public void incrementWinCount() {
winCount++;
}
/**
* This method allows you to check to see if this Team object has the same
* name as another Team object.
*
* This method allows you to use the contains method in ArrayList to see
* if any element in an array list has the same name as a specific Team.
*
* #param o
* the other Team being compared to.
*/
#Override
public boolean equals(Object o) {
return name.equals(((Team) o).name);
}
/**
* This method allows you to check to see if this Team object has the same
* name as another Team object
*
* #param otherTeam
* one team
*/
public boolean sameName(Team otherTeam) {
return name.equals(otherTeam.name);
}
/**
* This method allows you to check to see if this Team object has the same
* name as another Team object
*
* #param team1
* one team
* #param team2
* the other team
*/
public static boolean sameName(Team team1, Team team2) {
return team1.name.equals(team2.name);
}
/**
* This method allows you to sort an ArrayList of Team items using
* Collections.sort
*
* #param o
* the other Team being compared to.
* #return -1 if this Team item should come first, +1 if this Team item
* should come after the other, and 0 if this Team item is
* equivalent to the other.
*/
#Override
public int compareTo(Team o) {
if (this.winCount < o.winCount) {
return -1;
} else if (this.winCount > o.winCount) {
return 1;
}
return 0;
}
}
Here is my current code
Scanner scnr = new Scanner(System.in);
Random rando = new Random();
String name = "no";
int cycles = 0;
int value = 0;
int match = 0;
ArrayList<Team> teams = new ArrayList<Team>();
Team newTeam = new Team(name,1);
System.out.println("Welcome to the Advanced Sportsball Tracker!");
while (!name.equals("x")) // looping print statement
{ // x loop begins
System.out.println("Which team just won? (x to exit)");
match = 0;
cycles++;
name = scnr.next();
for (Team list : teams)
{
if (list.getName().equals(name)) // compares the name of the team to the input value
{
match++;
}
}
if (match == 0)
{
teams.add(newTeam);
}
}// x loop ends
System.out.print(newTeam.getName());
if (cycles == 1) // prints no data if user immediately exits
{
System.out.println("No data input");
}
if (cycles > 1)
{
System.out.println("Final Tally: "); // loop to print final Talley
for (Team list : teams) // FIXME
{
list.toString(list.getName(),list.getWinCount()); // makes a string out of the string and wincount of the team
}
What was the original code for the toString method they gave you? Did you add the parameters? A better way to do this would be to let the object use it's data fields inside of the method. Passing in the member variables in your for loop is unnecessary, and just bad code. Instead, you want to do something like this:
public String toString() {
return name + ": " + wins;
}
And in your loop, if you want to print the results, simply do this:
System.out.print(list.toString());
I have an assessment to do and I'm not good at programming. I can search for the algorithms and see how they are done, but in my case I have ordered collection of strings and somehow I have to use the get method.
I have these two classes that must not be changed:
public class SearchTest {
/**
* Test program for the Search class.
* Put whatever tests you like in the body of the method.
* #param args the command line arguments
* #throws java.io.IOException of error reading the input
*/
public static void main(String[] args) throws IOException {
// Don't change this line
final Search search = new Search();
// You can set this to any of the text files in the data folder
final FileStrings strings = new FileStrings("data/small.txt");
// add your tests here
System.out.println(search.longestWord(strings));
}
}
and
public class FileStrings implements StringList {
/** Underlying list of elements */
private final ArrayList<String> elements;
/** Number of calls to get() since the last call to resetCount() */
private int count;
/**
* Create a list containing the lines of a text file.
* #param fileName name of a text file of strings, in order
* #throws java.io.IOException on input error
*/
public FileStrings(String fileName) throws IOException {
elements = new ArrayList<>();
try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = input.readLine()) != null) {
elements.add(line);
}
}
count = 0;
}
/**
* Returns the number of elements in this list.
* This method takes constant time.
* #return the number of elements in this list
*/
#Override
public int size() {
return elements.size();
}
/**
* Returns the element at the specified position in this list.
* This method takes constant time.
* #param i position in the list, between 0 and size()-1
* #return the element at the position i
*/
#Override
public String get(int i) {
count++;
return elements.get(i);
}
/**
* Reset the count field.
*/
public void resetCount() {
count = 0;
}
/**
* Getter for count.
* #return number of calls to get() since the last resetCount()
*/
public int getCount() {
return count;
}
}
And my first task is to find the longest word from the given file list.
This is my attempt(I know it's wrong, but can't follow examples, because the solutions I see use the array directly):
public class Search {
/**
* Returns the index of the longest string in the list.
* If there are several string of this length, the
* indexed returned is the that of the first.
* #param a list of strings, in ascending order
* #return position of an entry with the longest string in the list
*/
public int longestWord(StringList a) {
int i=0;
int longestWord=0;
String nextWord=a.get(i+1);
String previousWord=a.get(i);
while (i < a.size() ) {
if (nextWord.length()>previousWord.length()){
longestWord = i;
}
i = i + 1;
}
return longestWord;
}
The result should be "14", the world "because" is the 15th word and is the longest. I hope you can help me with this!
list of words
public class Search {
/**
* Returns the index of the longest string in the list.
* If there are several string of this length, the
* indexed returned is the that of the first.
* #param a list of strings, in ascending order
* #return position of an entry with the longest string in the list
*/
public int longestWord(StringList a) {
int length=a.get(0).length();
int i=0;
int longestWord=0;
while (i<a.size()){
if (a.get(i).length()>length){
length=a.get(i).length();
longestWord=i;
}
i = i + 1;
}
return longestWord;
}
managed to do it :P
I am trying to create a fast search function to determine the prefix of a phone number.
I am loading prefix data from database into memory as TreeMap, where key is prefix and value is an object containing information about this prefix(country etc).
This is how TreeMap is populated:
private static TreeMap<String, PrefixData> prefixMap = new TreeMap<>();
//EXAMPLE of DB query
try {
Class.forName("org.postgresql.Driver");
Connection connection = DriverManager.getConnection(dbURL, dbUser, dbPass);
connection.setAutoCommit(false);
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM countries_prefixes");
//Looping resultset
while (rs.next()) {
//TODO Review fields that must be stored in memory
String country = rs.getString("name");
//Populating map with data object (keeping nr prefix as key and object as value)
prefixMap.put(rs.getString("country_prefix"), new PrefixData(country));
}
rs.close();
stmt.close();
connection.close();
} catch (ClassNotFoundException | SQLException e) {
System.out.println(e.toString());
}
Lets say I have phone numbers I want to check:
37251845632;
35844021546;
34651478966
etc ...
Some prefixes are 1 digit long, some 2 digits long, some 3 digits long and so on...
So I created a loop, that works:
//TODO Try some other search methods (Tries)
//array for prefix length priority
int[] sequence = {3, 4, 2, 1, 5, 6};
//Performing search from the map
for (int i = 0; i < sequence.length; i++) {
//Extracting prefix from phone nr
String prefix = phoneNr.substring(1, sequence[i] + 1);
if (prefixMap.containsKey(prefix)) {
PrefixData pdata = prefixMap.get(prefix);
System.out.println(String.format("Found matching key [%s] in TreeMap", prefix));
System.out.println(String.format("[NAME: %s] [REGEX: %s] ", pdata.getCountryName(), pdata.getNrRegex()));
//Validate number format with regex
if (pdata.getNrRegex().trim() != null && !pdata.getNrRegex().trim().isEmpty()) {
System.out.println("Regex for number validation is present!");
if (phoneNr.matches(pdata.getNrRegex().replaceAll("^/|/$", ""))) {
System.out.println("NUMBER IS VALID!");
} else {
System.out.println("INVALID NUMBER!");
}
}
return pdata;
}
}
return null;
}
Now the loop works well, but it is slow. I've heard something about Tries, which is faster, but I don't understand how to implement this in my scenario.
Any help is appreciated!
As I said, the loop works, but this is not a nice way to achieve my goal.
So I did a little bit of research and came up with solution that is using prefix tree (Trie) implementation.
Little reading what Trie is can be found here.
And now the Trie implementation part. I knew that it would be faster to find a code that is already written and tested, so I found Google implementation here. And Vladimir Kroz's implementation here.
Made some minor modifications and this is the solution. I will provide both solutions:
Prefixmap interface
package tiesImpl;
/**
* Maps string prefixes to values. For example, if you {#code put("foo", 1)},
* {#code get("foobar")} returns {#code 1}. Prohibits null values.
*
* <p>Use instead of iterating over a series of string prefixes calling
* {#code String.startsWith(prefix)}.
*
* #author crazybob#google.com (Bob Lee)
* #param <T>
*/
public interface PrefixMap<T> {
/**
* Maps prefix to value.
*
* #param prefix
* #param value
* #return The previous value stored for this prefix, or null if none.
* #throws IllegalArgumentException if prefix is an empty string.
*/
T put(CharSequence prefix, T value);
/**
* Finds a prefix that matches {#code s} and returns the mapped value.
*
* If multiple prefixes in the map match {#code s}, the longest match wins.
*
* #param s
* #return value for prefix matching {#code s} or {#code null} if none match.
*/
T get(CharSequence s);
}
PrefixTrie class
package tiesImpl;
/*
* Copyright (C) 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Trie implementation supporting CharSequences as prefixes.
*
* Prefixes are sequences of characters, and the set of allowed characters is
* specified as a range of sequential characters. By default, any seven-bit
* character may appear in a prefix, and so the trie is a 128-ary tree.
*
* #author crazybob#google.com (Bob Lee)
* #author mharris#google.com (Matthew Harris)
* #param <T>
*/
public class PrefixTrie<T> implements PrefixMap<T> {
// The set of allowed characters in prefixes is given by a range of
// consecutive characters. rangeOffset denotes the beginning of the range,
// and rangeSize gives the number of characters in the range, which is used as
// the number of children of each node.
private final char rangeOffset;
private final int rangeSize;
private final Node<T> root;
/**
* Constructs a trie for holding strings of seven-bit characters.
*/
public PrefixTrie() {
rangeOffset = '\0';
rangeSize = 128;
root = new Node<>(rangeSize);
}
/**
* Constructs a trie for holding strings of characters.
*
* The set of characters allowed in prefixes is given by the range
* [rangeOffset, lastCharInRange], inclusive.
*
* #param firstCharInRange
* #param lastCharInRange
*/
public PrefixTrie(char firstCharInRange, char lastCharInRange) {
this.rangeOffset = firstCharInRange;
this.rangeSize = lastCharInRange - firstCharInRange + 1;
if (rangeSize <= 0) {
throw new IllegalArgumentException("Char range must include some chars");
}
root = new Node<>(rangeSize);
}
/**
* {#inheritDoc}
*
* #param prefix
* #param value
* #throws IllegalArgumentException if prefix contains a character outside
* the range of legal prefix characters.
*/
#Override
public T put(CharSequence prefix, T value) {
if (value == null) {
throw new NullPointerException();
}
Node<T> current = root;
for (int i = 0; i < prefix.length(); i++) {
int nodeIndex = prefix.charAt(i) - rangeOffset;
try {
Node<T> next = current.next[nodeIndex];
if (next == null) {
next = current.next[nodeIndex] = new Node<>(rangeSize);
}
current = next;
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException(
"'" + prefix.charAt(i) + "' is not a legal prefix character.");
}
}
T oldValue = current.value;
current.value = value;
return oldValue;
}
/**
* {#inheritDoc}
* #param s
*/
#Override
public T get(CharSequence s) {
Node<T> deepestWithValue = root;
Node<T> current = root;
for (int i = 0; i < s.length(); i++) {
int nodeIndex = s.charAt(i) - rangeOffset;
if (nodeIndex < 0 || rangeSize <= nodeIndex) {
return null;
}
current = current.next[nodeIndex];
if (current == null) {
break;
}
if (current.value != null) {
deepestWithValue = current;
}
}
return deepestWithValue.value;
}
/**
* Returns a Map containing the same data as this structure.
*
* This implementation constructs and populates an entirely new map rather
* than providing a map view on the trie, so this is mostly useful for
* debugging.
*
* #return A Map mapping each prefix to its corresponding value.
*/
public Map<String, T> toMap() {
Map<String, T> map = newLinkedHashMap();
addEntries(root, new StringBuilder(), map);
return map;
}
/**
* Adds to the given map all entries at or below the given node.
*
* #param node
* #param builder A StringBuilder containing the prefix for the given node.
* #param map
*/
private void addEntries(Node<T> node,
StringBuilder builder,
Map<String, T> map) {
if (node.value != null) {
map.put(builder.toString(), node.value);
}
for (int i = 0; i < node.next.length; i++) {
Node<T> next = node.next[i];
if (next != null) {
builder.append((char) (i + rangeOffset));
addEntries(next, builder, map);
builder.deleteCharAt(builder.length() - 1);
}
}
}
private static class Node<T> {
T value;
final Node<T>[] next;
#SuppressWarnings("unchecked")
Node(int numChildren) {
next = new Node[numChildren];
}
}
/**
* Creates a {#code LinkedHashMap} instance.
*
* #param <K>
* #param <V>
* #return a newly-created, initially-empty {#code LinkedHashMap}
*/
public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
return new LinkedHashMap<>();
}
}
Vladimir Kroz implementation: Trie class
package tiesImpl;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Prefix table based on Trie structure. Allows to perform incremental lookup
* and match based on search key prefixes (classic example - determine phone
* area code for given phone number)
*
* #param <V> a type of value object to be stored along with prefix (e.g when
* key is a country name, the value could be a name of the country)
*
* #author Vladimir Kroz
* https://vkroz.wordpress.com/2012/03/23/prefix-table-trie-implementation-in-java/
*/
public class Trie<V> {
Entry<V> entry;
char key;
Map<Character, Trie<V>> children;
public Trie() {
this.children = new HashMap<>(10);
entry = new Entry<>();
}
/**
* non-public, used by _put()
*/
Trie(char key) {
this.children = new HashMap<>(10);
this.key = key;
entry = new Entry<>();
}
public void put(String key, V value) {
_put(new StringBuffer(key), new StringBuffer(""), value);
}
void _put(StringBuffer remainder, StringBuffer prefix, V value) {
if (remainder.length() > 0) {
char keyElement = remainder.charAt(0);
Trie<V> t = null;
try {
t = children.get(keyElement);
} catch (IndexOutOfBoundsException e) {
}
if (t == null) {
t = new Trie<>(keyElement);
children.put(keyElement, t);
}
prefix.append(remainder.charAt(0));
t._put(remainder.deleteCharAt(0), prefix, value);
} else {
this.entry.value = value;
this.entry.prefix = prefix.toString();
}
}
/**
* Retrieves element from prefix table matching as a prefix to provided
* key. E.g. if key is "37251656565" and prefix table has node "372" then
* this call will return the value of "372"
*
* #param key a string which starts with prefix to be searched in the table
* (e.g. phone number)
* #return an Object associated with matching prefix (i.e if key is a phone
* number it may return a corresponding country name)
*/
public V get(String key) {
return _get(new StringBuffer(key), 0);
}
/**
* Returns true if key has matching prefix in the table
*
* #param key
* #return
*/
public boolean hasPrefix(String key) {
return this.get(key) != null;
}
V _get(StringBuffer key, int level) {
if (key.length() > 0) {
Trie<V> t = children.get(key.charAt(0));
if (t != null) {
//FYI: modified code to return deepest with value instead of returning null if prefix doesn't have corresponding value.
V result = t._get(key.deleteCharAt(0), ++level);
return result == null ? entry.value : result;
} else {
return (level > 0) ? entry.value : null;
}
} else {
return entry.value;
}
}
#Override
//For debugging
public String toString() {
Iterator<Character> it = children.keySet().iterator();
StringBuffer childs = new StringBuffer();
while (it.hasNext()) {
Character _key = it.next();
childs.append(String.format("\n%s\n",
//Adding a tab to the beginning of every line to create a visual tree
String.format("%s: %s", _key, children.get(_key)).replaceAll("(?m)(^)", "\t")));
}
return String.format("Trie [entry=%s, children=%s]", entry, childs);
}
static public class Entry<V> {
String prefix;
V value;
public Entry() {
}
public Entry(String p, V v) {
prefix = p;
value = v;
}
public String prefix() {
return prefix;
}
public V value() {
return value;
}
#Override
public String toString() {
return "Entry [prefix=" + prefix + ", value=" + value + "]";
}
}
}
And finally the Testing part
package tiesImpl;
/**
* Class for testing different implementations of prefix tree (Trie).
*
* #author lkallas
*/
public class TriesTest {
private static final PrefixTrie<String> googleTrie = new PrefixTrie<>();
private static final Trie<String> krozTrie = new Trie<>();
public static void main(String[] args) {
//Inserting prefixes to Google implementation of Trie
googleTrie.put("7", "Russia");
googleTrie.put("77", "Abkhazia");
googleTrie.put("746", "Some unknown country");
//Inserting prefixes to Vladimir Kroz implementation of Trie
krozTrie.put("7", "Russia");
krozTrie.put("77", "Abkhazia");
krozTrie.put("746", "Some unknown country");
System.out.println("Google version of get: " + googleTrie.get("745878787"));
System.out.println("Vladimir Kroz version of get: " + krozTrie.get("745878787"));
}
}
Hope that this answer is somewhat helpful to others also!
Cheers!