Printing grouped by values - java

I have written below code to print the Search objects in the groups map. But I am not getting the correct output.
Mycode:
Map<Integer, List<Search>> groups = group.stream().collect( Collectors.groupingBy( w -> w.getId()) );
System.out.println( groups );
Output I get:
{
1=[Models.Search#30269b0d],
2=[Models.Search#423e11a8],
3=[Models.Search#25e2f879]
}
I want my output to print the grouped Search objects. Please help.
Edited:
sample output I want
{
1=[Michael/14/UK/90, Tim/15/UK/91, George/14/UK/98],
2=[Jan/13/POLAND/92, Anna/15/POLAND/95],
3=[Helga/14/GERMANY/93, Leon/14/GERMANY/97]
}

Override the toString() method in Search class and return your custom String based on the fields that you want to have in the output. What you see here is simply the objects reference.
Edit for sake of completeness:
#Override
public String toString() {
return res=name+"/"+someNumber+"/"+country+"/"+someOtherNumber;
}

In your class Search,override toString like
#Override
public String toString() {
String res=value1+"/"+value2+"/"+...
return res;
}

Related

Java String... question regarding multiple inputs for a method

is it possible to create a class and have a String ... attribute that takes as many or as little strings as you put?
example:
please excuse my rough pseudocode, this is for java.
//this is the method:
public void getXXXX(String ...) {
//random code executes in a loop with as many as strings that are inputted
}
//this code calls it
getXXXX("Benjamin","Jordan","Steve")
getXXXX("Pengu","No")
getXXXX("hi")
Yes, what you entered will more or less work, you just need a parameter name after your type.
class StringDecorator {
public static String join(final String... strings) {
final var builder = new StringBuilder();
for (final var string : strings) {
builder.append(string);
}
return builder.toString();
}
}
Then invoke this somewhere
StringDecorator.join("Hello, ", "World!"); // "Hello, World!"

Private Sorting Rule in a Stream Java

Hey if anyone has an idea I would be really thankfull.
I'm in a Java stream and i would like to sort my list that i'll be returning.
I need to sort the list via TradPrefis ( MyObject::getTradPrefix ).
But this would be way too easy. Because i want to sort following the number at the end of TradPrefix exampleTradPrefix_[NUMBER TO SORT]
Exemple : hello_1
test_2
...
still_there_22
Here is a piece of code so you can imagine easier.
public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
return (toReturn.stream()
.map(this::createWsQuestion)
.sorted(comparing(WsQuestion::getTradPrefix.toString().length()))
.collect(Collectors.toCollection(LinkedHashSet::new)));
}
One method would simply be to split getTradPrefix().toString() by _ and parse the rightmost value as an int, and use it to sort the Stream:
public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
return toReturn.stream()
.map(this::createWsQuestion)
.sorted(Comparator.comparingInt(question -> {
String[] args = question.getTradPrefix().toString().split("_");
return Integer.parseInt(args[args.length - 1]);
}))
.collect(Collectors.toCollection(LinkedHashSet::new));
}
If I where you I would simply put a method on the WsQuestion class, let's call it sort order:
public int getSortOrder() {
return Integer.valueOf(tradPrefix.substring(tradPrefix.lastIndexOf("_") + 1));
}
The Integer parse is needed since comparing strings would give "11" < "2" (thanks Holger for pointing this out). The lastIndexOf() makes sure that any number of underscores are allowed in tradPrefix, as long as there is at least one.
Then simply create a comparotor by using Comparator.comparingInt()
public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
return (toReturn.stream()
.map(this::createWsQuestion)
.sorted(comparingInt(WsQuestion::getSortOrder))
.collect(Collectors.toCollection(LinkedHashSet::new)));
}
You can make a small Comparator like this:
private static final Comparator<String> questionComparator = Comparator.comparingInt(s -> {
String[] pieces = s.split("_");
return Integer.parseInt(pieces[pieces.length-1]);
});
Then use it in your sorted().
Having a separate Comparator will make your code more readable too, since you will be separating concerns.
return toReturn.stream()
.map(this::createWsQuestion)
.sorted(questionComparator)
.collect(Collectors.toCollection(LinkedHashSet::new));

Pertaining to Array Lists and the toString Method

I am currently in a Java AP Computer Science class and we have been required to complete an activity that can do the following:
The class TransactionHistory is used to keep track of a sequence of Transactions. Complete the following definition for this class by providing the body of the toString method, which returns a multiline String consisting of the output from the toString method of each Transaction, each on a new line. (Recall that a String may be broken into multiple lines by including "\n".)
Be careful, though, to ensure that your toString method does not return a String that ends with a newline character. To help you with this, we provide (behind the scenes) a showNewlines method for you to use when testing your toString method. Examine the code inserted by the provided test cases to see how it may be used.
So far, I have the following code:
public class TransactionHistory extends ArrayList<Transaction>
{
public String toString()
{
for (Transaction t : this) {
return t.toString();
}
return "";
}
}
And this is one of the test cases that we are required to use:
public static void main( String[] args )
{
TransactionHistory th = new TransactionHistory();
th.add( new Deposit( 100.0, "10:15", "10/23/2007" ) );
th.add( new Deposit( 2.35, "11:05", "9/21/2007" ) );
th.add( new Withdrawal( 50.0, "2:24", "11/1/2007" ) );
System.out.println( showNewlines( th.toString() ) );
}
With the code that I have currently, all it is capable of doing is printing out the first line of transactions.
Here is what is printed out:
Deposit 100.0 10:15 10/23/2007
How would I go about making the code print out all of the transactions that were added?
Thank you, all help is appreciated.
Your return statement is breaking your loop as it already returns the first Transaction:
for (Transaction t : this) {
return t.toString();
}
Use a StringBuilder to append each, then return StringBuilder#toString()
be careful, the problem indicates that your toString() DOES NOT RETURN THE STRING THAT ENDS WITH A NEWLINE CHARACTER which is a different story in itself.
substring(int beginIndex, int endIndex) and lastIndexOf(String str) should take care of that.
String a = "foo\nbar\n";
System.out.println(a.substring(0, a.lastIndexOf("\n")));
Hope this helps.

Get the Objects out of a list Java

Im doing a little text adventure. Im current working on a inventory. I tried to do my inventory with a list:
ArrayList<Object> inventar = new ArrayList<Object>();
I initialize Objects as Items:
Item holzschwert = new Item("Holzschwert", 1, 5);
inv.addToInventar(holzschwert);
Here's my add Method:
public void addToInventar(Object ...item){
inventar.add(item);
}
But everytime i want to print out my inventory (here's my toString() function) i still get the Hash code:
#Override
public String toString() {
return "Inventar [ Inventar = " + inventar + " ]";
}
and my print method
Object test = inv.getInventar();
String ausgabe = inv.toString();
System.out.println(ausgabe);
and the console log:
Inventar [ Inventar = [[Ljava.lang.Object;#281c35ec] ]
Thank you for your help :)
The mistake is
public void addToInventar(Object ...item){
inventar.add(item);
}
Here item is an Object[], because you used varargs (...). What you are seeing is the result of calling toString on an array.
You want
public void addToInventar(Object item){
inventar.add(item);
}
or possibly
public void addToInventar(Object... items){
for (Object item : items)
inventar.add(item);
}
EDIT
In addition to this answer, I should point out that you should probably not be using List<Object> anyway. List<Item> would be better as mistakes like this are more likely to be spotted by the compiler. The signature addToInventar(Object... items) should really be avoided like the plague, as it will accept literally any sequence of arguments of any length. All reference types are Objects and all primitives can be autoboxed.
Override the Item class toString() method.
class Item{
#override
public String toString(){
//Give your implementation
}
}
#Override
public String toString() {
StringBuffer stuff = new StringBuffer();
for (Object item : inventar) {
stuff.append(item.getName()); // you need a getter for the item name
stuff.append(" ");
}
return stuff.toString();
}
Both your inventory and items are Objects. If you just print the objects and not the fields you will only get their memory address as output:
Ljava.lang.Object;#281c35ec
not the properties you've set up for them.
If you do not care about the exact format of the output, you can do something like this in your Item class:
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
ToStringBuilder is part of the Apache Commons Lang library. If you want it specifically formatted a certain way, then go with #Code Whisperer and write your own implementation.

polymorphic binary search tree

I have 2 classes, NonEmptyTree and EmptyTree that implement the Tree interface. toString() method in NonEmptyTree class should return a string: key=>value key=>value key>value etc...
I do not know how to remove last space at end of result.
EDIT: I cannot use any methods in the String class, and I cannot compare anything to null.
public String toString() {
String result = "";
result+=(this.left.toString());
result+=this.key;
result+="=>";
result+=this.value;
result+=" ";
result+=this.right.toString();
return result;
}
I've tried having a variable for the class that indicates if a NonEmptyTree instance is the largest in the current tree, but console displayed same string.
for example, the string would look like this:
"7=>seven 10=>ten 12=>twelve 15=>fifteen 16=>sixteen 17=>seventeen 20=>twenty 30=>thirty "
any help would be appreciated. thanks
Use String.trim():
return result.trim()
BTW. if you do a lot of String additions it's better to use StringBuilder and its method append() instead of adding multiple Strings with +.
public String toString() {
StringBuilder result = new StringBuilder();
result.append(this.left.toString());
result.append(this.key);
result.append("=>");
result.append(this.value);
result.append(" ");
result.append(this.right.toString());
return result.toString().trim();
}
Can you simply add an 'if'? See below:
public String toString()
{
String result = "";
result+=(this.left.toString());
result+=this.key; result+="=>";
result+=this.value;
if (this.right!=null) // Just add this, so it doesn't add an extra space if no right result exists
{
result+=" ";
result+=this.right.toString();
}
return result;
}

Categories