Make a custom ArrayList toString() that displays contents line by line? - arrays

I understand with toString() methods, their must be a return type, when an external method is called.
The comment block below describes what I'm trying to do.
Later on when I work with setters and getters, this knowledge will most definitely be invaluable.
import java.util.*;
public class Display_ArrayList {
static ArrayList<String> cars = new ArrayList<String>();
public static void main(String[] args) {
cars.add("Nissan Maxima");
cars.add("Toyota Prius");
cars.add("Renault Clio");
cars.add("Ford Focus");
cars.add("Volkwagen Passat");
System.out.println("");
System.out.println("[Standard toString()]:");
System.out.println(cars.toString());
System.out.println("");
System.out.println("[Custom toString()]:");
System.out.println(custom_cars_toString());
}
// Array list displays the car list all on the same line
public static String getCarList() {
return cars.toString();
}
// *************************************************************************
// I want Array list contents to be displayed on their own lines without
// commas or brackets, while at the same allowing this method to be
// retrieved by a toString() method
// *************************************************************************
// public static void getCarList() {
// for (String element : cars)
// System.out.println(element);
// }
public static String custom_cars_toString() {
return "The cars contained are: \n" + getCarList();
}
}

Can't you just make a class that extends ArrayList which overrides the toString method? Then you could make something like this:
public class DisplayArrayList<T> extends ArrayList {
#Override
public String toString() {
String res = "";
for (int i = 0; i < size(); i++) {
res += (i == 0 ? "" : "\n") + get(i).toString();
}
return res;
}
}
Then you can just put your cars in a DisplayArrayList instead of an ArrayList and then when you print that you will get them all on individual lines.
For example this:
DisplayArrayList<String> list = new DisplayArrayList<>();
list.add("test1");
list.add("test2");
list.add("test3");
list.add("test4");
list.add("test5");
System.out.println(list);
Would output this:
test1
test2
test3
test4
test5
Sorry if this doesn't do what you want to, couldn't completely figure out what you want from your post.

Related

Radix sort with array of custom linked lists - error trying to print

I have an assignment for class and we have to use a radix sort using an array of linked lists.
It should split a string into a key and value, and store them as an Entry.
public class Entry {
public String key;
public String value;
public Entry() {
}
public Entry(String key, String value) {
this.key = key;
this.value = value;
}
}
The Entry class is pretty basic, I dont think it has any problems.
The issue is that I can either get the while loop to iterate exactly once and then the program completely stops, or I can cause an infinite loop depending on whether or not I use array[10].removeHead() twice or not
import java.io.File; // Import the File class
import java.io.FileNotFoundException; // Import this class to handle errors
import java.util.Scanner; // Import the Scanner class to read text files
public class RadixSort {
public static void main(String[] args) {
try {
LinkedList[] array = new LinkedList[11];
for(int i = 0; i < 11; i++) {
array[i] = new LinkedList();
}
File myObj = new File("years.txt");
Scanner myReader = new Scanner(myObj);
int counter = Integer.parseInt(myReader.nextLine());
System.out.println(counter);
while (myReader.hasNextLine()) {
String string = myReader.nextLine();
if (string.equals("END")) break;
String[] parts = string.split(",");
String part1 = parts[0];
String part2 = parts[1];
Entry a = new Entry(part1, part2);
array[10].addTail(a);
//System.out.println(array[ 0].removeHead().key);
// this works, but gives null ptr exception^^^
System.out.println(array[10].peekHead().key + "," + array[10].peekHead().value);
array[10].removeHead();
}
for (int i = counter; i > 0; i--) {
while (!array[10].peekHead().key.contains(null)) {
String s = array[10].peekHead().key;
String g = array[10].peekHead().value;
int a = Integer.parseInt(s.substring(i-1));
System.out.println(a);
//System.out.println(s);
Entry bruh = new Entry(s, g);
array[a].addHead(bruh);
if (s.equals(null)) System.out.println("error");
//System.out.println(array[10].peekHead().key);
//System.out.println(array[a].peekHead().value);
array[10].removeHead();
System.out.println(array[a].peekHead().key);
}
for (int j = 0; j < 10; j++) {
while (!array[j].peekHead().key.equals(null)) {
array[10].addTail(array[j].removeHead());
}
}
}
while (!array[10].peekHead().key.equals(null)) {
System.out.println(array[10].peekHead().key + "," + array[10].peekHead().value);
array[10].removeHead();
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}
When I try to print it out it just prints the first Node a bunch of times and then throws a NullPointerException like below:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.CharSequence.toString()" because "s" is null
at java.base/java.lang.String.contains(String.java:2054)
at RadixSort.main(RadixSort.java:34)
My linked list class should work fine, I did it for our first assignment and tested it pretty thoroughly and it had no errors that I could see.
I tried to just add a couple more removeHead() functions to see if that would change anything and it just keeps throwing that dumb null pointer exception. If anyone could help with anything I would be incredibly grateful.

How to discover the reason for an error in my simple test class?

This is my aura method to retrieve fields for dual list box.
#AuraEnabled
public static List <String> getProperties(sObject objObject, string sFieldAPI) {
List < String > lstOptions = new list < String > ();
Schema.sObjectType objType = objObject.getSObjectType();
Schema.DescribeSObjectResult objDescribe = objType.getDescribe();
map <String, Schema.SObjectField> fieldMap = objDescribe.fields.getMap();
list < Schema.PicklistEntry > values =fieldMap.get(sFieldAPI).getDescribe().getPickListValues();
for (Schema.PicklistEntry a: values) {
lstOptions.add(a.getValue());
}
lstOptions.sort();
return lstOptions;
}
And this is the test class where I'm getting error.
testMethod static void testGetProperties(){
setupInsertData();
Test.startTest();
List<String> Prop = MessageTypeController.getProperties('isArray');
System.debug('Test Category'+Prop);
if(Prop!=null){
System.assertEquals(Prop!=null,true);
}else{
System.assertEquals(Prop==null,true);
}
Test.stopTest();
}
The text of the error is:
"Method does not exist or incorrect signature: void getProperties(String)"
You / your colleague defined getProperties(sObject objObject, string sFieldAPI) but you're trying to call it with getProperties('isArray'). There's no method with 1 parameter (at least not in the code snippet you pasted).
You probably want to call it with something like
MessageTypeController.getProperties(new Opportunity(), 'StageName');
With this now it's working:
testMethod static void testGetProperties(){
setupInsertData();
Test.startTest();
skyvvasolutions__MessageType__c msg = new skyvvasolutions__MessageType__c();
List<String> Prop = MessageTypeController.getProperties(msg, 'skyvvasolutions__Properties__c');
System.debug('Test Category'+Prop);
if(Prop!=null){
System.assertEquals(Prop!=null,true);
}else{
System.assertEquals(Prop==null,true);
}
Test.stopTest();
}

nullpointerexception for array of objects

I have the following test class
public class Driver
{
public static void main(String [] args)
{
BankAccount[] b1 = {new BankAccount(200), new BankAccount(300), new BankAccount(250), new BankAccount(300), new BankAccount(200)};
BankAccountGroup bag = new BankAccountGroup(b1);
}
And BankAccountGroup:
public class BankAccountGroup
{
private BankAccount bank[];
public BankAccountGroup(BankAccount[]b)
{
for(int i =0; i<5;i++)
{
bank[i] = b[i];
}
}
these are just snippets of the whole code. Im getting a nullpointerexception for these two lines:
- bank[i] = b[i];
- BankAccountGroup bag = new BankAccountGroup(b1);
Please help
When you declare bank[] in the BankAccountGroup class it looks like you forgot to give it a length. Because of this, when you call bank[i] in your for loop, anything after i=0 is probably going to give you an error.
something like
private BankAccount[] bank = new BankAccount[5];
Either initialize your array first(Bad).
Or assign it from the value you pass the constructor.
private BankAccount[] bank;
public BankAccountGroup(BankAccount []){
bank = b;
}
You are not initializing the bank array. You also shouldn't assume that the argument will have a length of 5 elements. I would rewrite the class to something like this:
public class BankAccountGroup
{
private BankAccount bank[];
public BankAccountGroup(BankAccount[]b)
{
if (b != null)
{
bank = new BankAccount[b.length];
for(int i=0; i<b.length;i++)
{
bank[i] = b[i];
}
}
}
}

interface with iterate array loop

I am getting problems with these 2 lines. I need to create a class with an array of Animals using constants to size it. I have to fill the array Animal with Fish and Iterate in 2 different ways through the array executing move() and makeSound().
These are the lines:
1 animals[0] = new Fish()
2 for (Animal animal : animals) {
public class Animals {
public static void main(String[] args) {
final int SIZE = 6;
Animal animal[] = new Animal[SIZE];
animals[0] = new Fish() // 1
for (Animal animal : animals) { // 2
System.out.println("Bubbles");
System.out.println("Swim");
}
}
}
My interface Animal:
public interface Animal {
public void move();
public void makeSound();
}
And my class Fish that implements Animal
public class Fish implements Animal{
#Override
public void move() {
System.out.println("Swim");
}
#Override
public void makeSound() {
System.out.println("Bubbles");
}
private String color;
public String getColor(){
return color;
}
public void setColor(String color){
this.color = color;
//Prefix this.color;
}
}
A couple of syntax errors to fix:
Add a semicolon to the end of animals[0] = new Fish();
Change Animal animal[] = new Animal[SIZE]; to Animal[] animals = new Animal[SIZE];
Also, you should really be doing this in the for loop:
for(Animal animal : animals){
animal.makeSound();
animal.move();
}
Just hard-coding print statements defeats the purpose of having the Animal interface, even if Fish is the only class implementing Animal at the moment.

Passing a list or array to RESTeasy using get

I've seen this kind of thing described in various examples showing how to create a REST service which takes arrays or a list of objects as part of the URL.
My question is, how to implement this using RESTeasy?
Something like the following would be how i would assume this to work.
#GET
#Path("/stuff/")
#Produces("application/json")
public StuffResponse getStuffByThings(
#QueryParam("things") List<Thing> things);
Create a StringConverter and a use a wrapper object. Here is a quick and dirty example:
public class QueryParamAsListTest {
public static class Thing {
String value;
Thing(String value){ this.value = value; }
}
public static class ManyThings {
List<Thing> things = new ArrayList<Thing>();
ManyThings(String values){
for(String value : values.split(",")){
things.add(new Thing(value));
}
}
}
static class Converter implements StringConverter<ManyThings> {
public ManyThings fromString(String str) {
return new ManyThings(str);
}
public String toString(ManyThings value) {
//TODO: implement
return value.toString();
}
}
#Path("/")
public static class Service {
#GET
#Path("/stuff/")
public int getStuffByThings(
#QueryParam("things") ManyThings things){
return things.things.size();
}
}
#Test
public void test() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getProviderFactory().addStringConverter(new Converter());
dispatcher.getRegistry().addSingletonResource(new Service());
MockHttpRequest request = MockHttpRequest.get("/stuff?things=a,b,c");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
Assert.assertEquals("3", response.getContentAsString());
}
}
I think you can also use a StringParamUnmarshaller
I had some luck with this, using Collection rather than List. I was unable to make a StringConverter for List work.
#Provider
public class CollectionConverter implements StringConverter<Collection<String>> {
public Collection<String> fromString(String string) {
if (string == null) {
return Collections.emptyList();
}
return Arrays.asList(string.split(","));
}
public String toString(Collection<String> values) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
for (String value : values) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(value);
}
return sb.toString();
}
}
I did the toString from my head. Be sure to write unit tests for it to verify. But of course, everything is easier and clearer when you use Guava. Can use Joiner and Splitter. Really handy.
Just use a wrapper on its own, no need for anything else.
In your endpoint
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Path("/find")
#GET
MyResponse find(#QueryParam("ids") Wrapper ids);
And you wrapper looks like this :
public class Wrapper implements Serializable {
private List<BigInteger> ids = Collections.emptyList();
public String toString() {
return Joiner.on(",")
.join(ids);
}
public List<BigInteger> get() {
return ids;
}
public Wrapper(String s) {
if (s == null) {
ids = Collections.emptyList();
}
Iterable<String> splitted = Splitter.on(',')
.split(s);
Iterable<BigInteger> ids = Iterables.transform(splitted, Functionz.stringToBigInteger);
this.ids = Lists.newArrayList(ids);
}
public Wrapper(List<BigInteger> ids) {
this.ids = ids;
}
}

Resources